F. Discussion

For Yahtzee Dawg

a. Game’s Testing

During the testing phase of the Yahtzee game developed in MATLAB, several key observations and outcomes were noted:

  1. Game Initialization and Setup:
    • The game environment setup, including clearing the MATLAB workspace and initializing the game engine, was successful. The welcome message and game rules were displayed correctly.
    • Variables for dice faces, selected/unselected dice sprites, current player, total rounds, scoring categories, and their descriptions were initialized without issues.
  2. Player Input and Validation:
    • The game correctly prompted for the number of players and validated the input to ensure it was a positive integer.
  3. Gameplay Mechanics:
    • The main game loop functioned as intended, allowing each player to take turns in rolling the dice.
    • The dice rolling mechanism, including the random generation of dice faces and the option for re-rolls, worked effectively.
    • Players were able to select dice to keep for re-rolling, and the game accurately reflected these choices in subsequent rolls.
  4. Scoring System:
    • The scoring system was a critical aspect of the game’s testing. Each scoring category functioned as expected, and the game correctly calculated and updated scores based on the chosen category and dice outcome.
    • The game prevented players from selecting a scoring category more than once, aligning with the rules of Yahtzee.
  5. End of Game:
    • Upon completion of all rounds, the game successfully calculated total scores, including any bonuses.
    • The game correctly identified the winner(s) based on the highest score and displayed the appropriate message.
    • The option to play another game functioned correctly, allowing for continuous gameplay.

b. Progression of the MATLAB Code

The MATLAB code for the Yahtzee game progressed through several stages:

  1. Initial Setup:
    • The code began with setting up the game environment, including initializing the game engine and defining essential variables.
  2. Player Interaction:
    • The code included mechanisms for player interaction, such as input for the number of players and choices for dice re-rolls.
  3. Game Loop Development:
    • A significant part of the code was dedicated to the main game loop, handling player turns, dice rolling, and scoring.
  4. Scoring Mechanism:
    • The scoring mechanism was carefully developed to align with Yahtzee’s rules. This included calculating scores for different categories and ensuring that each category could only be scored once per game.
  5. End-Game Logic:
    • The code included logic to conclude the game after all rounds, calculate total scores, and determine the winner(s).
  6. User Experience Enhancements:
    • Throughout the development, enhancements were made to improve the user experience, such as clear instructions, feedback on actions, and the option to play multiple games.

c. Describe the obstacles faced and how they were overcome:

(1). Ensuring Valid Player Input: Overcoming Input Validation Challenges in Yahtzee’s MATLAB Implementation

In Step 2 of the Yahtzee game’s MATLAB code, a significant obstacle encountered was ensuring that players input a correct positive integer for the number of players. This challenge was crucial to address because the game’s progression depends on the accurate and valid input of the number of players.

To overcome this obstacle, the following approach was implemented in the code:

  1. Player Input for Number of Players:
    • The code initially prompts the user to input the number of players using the ‘input’ function: numberOfPlayers = input(‘Enter the number of players: ‘);
    • This step is critical as it sets the stage for the game’s dynamics, including the initialization of scores and turns.
  2. Validation of Input:
    • To ensure that the input is a positive integer, a validation loop is used. The code checks if the input is less than or equal to zero or if it is not an integer. This is done using the ‘floor’ function, which rounds down to the nearest integer.
    • The validation loop is structured as follows:
      while numberOfPlayers <= 0 || floor(numberOfPlayers) ~= numberOfPlayers
      fprintf(‘The number of players must be a positive integer.\n’);
      numberOfPlayers = input(‘Enter the number of players: ‘);
      end
    • This loop continues to prompt the user for input until a valid positive integer is entered. The use of ‘floor(numberOfPlayers) ~= numberOfPlayers’ effectively checks whether the input is an integer by comparing the input with its floored value. If they are not equal, it indicates that the input was not an integer.
  3. Ensuring Correct User Input:
    • The combination of the input function and the validation loop ensures that the game receives correct user input. It prevents the game from proceeding with invalid or non-integer values, which could lead to errors or unexpected behavior in the game’s logic.

By implementing this approach, the code effectively handles user input for the number of players, ensuring that the game progresses smoothly with valid and appropriate input. This solution demonstrates a fundamental aspect of programming: anticipating and handling user input variations to maintain the integrity and functionality of the application.

(2). Navigating Player Choices: Addressing Dice Selection and Input Validation in Yahtzee’s MATLAB Code

In Step 4 of the Yahtzee game’s MATLAB code, a significant challenge was managing the player’s choice of which dice to keep for re-rolling and ensuring that the input for dice selection was correct and valid. This step is crucial as it directly affects the game’s outcome and player strategy.

To address these challenges, the following approach was implemented in the code:

  1. Asking Players Which Dice to Keep:
    • The code prompts players to decide if they want to re-roll any dice. This is done using the ‘input’ function with a custom message:
      reRollChoice = input(‘Do you want to re-roll any of your dice? Press enter to choose some dice to keep or enter “no” to start scoring a category’, ‘s’);
    • If the player chooses not to re-roll (strcmpi(reRollChoice, ‘no’)), the game highlights all dice to indicate the final choice and moves to the scoring phase.
  2. Validating Player Input for Dice Selection:
    • If the player opts to re-roll, the game asks which dice they want to keep. The input is taken as a string and then converted to numbers using ‘str2num’:
      keepDiceInput = input(”, ‘s’);
      keepDice = str2num(keepDiceInput);
      To ensure the input is valid (i.e., all numbers should be between 1 to 5), the code uses the ‘ismember’ function combined with a check for empty input:
    • if all(ismember(keepDice, 1:5)) || isempty(keepDice)
      validInput = true;
      else
      fprintf(‘Invalid input. Please enter numbers from 1 to 5 only.\n’);
      end
    • This validation loop continues until the player enters a valid response.
  3. Highlighting and Re-rolling Dice:
    • Once valid input is received, the code highlights the dice the player chose to keep and re-rolls the others:
      diceBackgrounds = unselectedDieSprite * ones(1, 5);
      diceBackgrounds(keepDice) = selectedDieSprite;
      for i = 1:5
      if ~ismember(i, keepDice)
      diceRolls(i) = randi(6);
      end
      end
    • The dice face sprites are updated with the new rolls, and the game display is refreshed to show the updated roll with highlighted kept dice.

By implementing this approach, the code effectively manages the player’s choice of dice for re-rolling and ensures that the input for dice selection is correct and valid. This solution demonstrates careful consideration of user interaction and input validation, which are crucial for maintaining the integrity and playability of the game.

(3). Streamlining Scoring and Category Selection: Tackling Challenges in Yahtzee’s Scoring Mechanism

In Step 5 of the Yahtzee game’s MATLAB code, the challenges revolved around implementing a robust scoring system and ensuring players choose a valid and correct category for their score. These challenges were critical to address as they directly impact the gameplay and the fairness of the scoring mechanism.

To overcome these challenges, the following approach was implemented in the code:

  1. Displaying Scoring Categories:
    • The code first displays all the scoring categories in the command window to inform the player of their options. This is achieved through a loop that iterates over the ‘categoriesDescriptions’ array:
      for i = 1:length(categoriesDescriptions)
      fprintf(‘%s\n’, categoriesDescriptions(i));
      end
  2. Validating Player’s Category Choice:
    • Players are prompted to choose a scoring category by entering a number corresponding to the category. The code ensures that the input is valid and that the chosen category has not been scored previously by the player:
      category = 0;
      while (category < 1 || category > length(categories)) || categoriesChosen(currentPlayer, category) == 1
      category = input(‘Choose a scoring category by number (1-13): ‘);
      if category < 1 || category > length(categories)
      fprintf(‘Invalid category. Please choose a number between 1 and 13.\n’);
      elseif categoriesChosen(currentPlayer, category) == 1
      fprintf(‘Category “%s” has already been scored. Please choose a different category.\n’, categories(category));
      end
      end
    • This loop continues until the player selects a valid and unused category.
  3. Calculating and Updating Scores:
    • Once a valid category is chosen, the code calculates the score for that category based on the dice rolls. This is done using a ‘switch’ statement that covers all possible categories:
      switch category
      case 1 % Aces
      playerScores(currentPlayer, category) = sum(diceRolls(diceRolls == 1));
      % … other cases for different categories …
      case 13 % Yahtzee
      if isYahtzee(diceRolls)
      playerScores(currentPlayer, category) = 50;
      else
      playerScores(currentPlayer, category) = 0;
      end
      end
    • The score for each category is calculated based on the specific rules of Yahtzee, and the player’s score is updated accordingly.

By implementing this approach, the code effectively manages the scoring process, ensuring that players can only select valid and unused categories and accurately calculates their scores based on their dice rolls. This solution demonstrates a careful consideration of game rules and player interaction, which are crucial for maintaining the integrity and competitive balance of the game.

(4). Mastering End-Game Logic: Addressing Scoring, Bonus Calculation, and Winner Determination in Yahtzee’s MATLAB Code

In Step 6 of the Yahtzee game’s MATLAB code, several challenges were encountered related to calculating bonuses and scores, displaying final scores for each player, and determining the winner, especially in scenarios with multiple winners. Here’s how these challenges were addressed:

  1. Calculating Bonuses and Scores:
    • The challenge was to accurately calculate and apply bonuses based on the game’s rules. The code addresses this by first defining constants related to scoring:
      upperSectionIndices = 1:6; % Indices for Aces through Sixes
      upperSectionBonusThreshold = 63; % Minimum score for bonus
      upperSectionBonusPoints = 35; % Bonus points awarded

      These constants provide a clear reference for which scores contribute to the bonus and the criteria for earning it.

    • The total scores for each player are initially calculated by summing up their scores across all rounds. The code then iterates through each player’s upper section scores to determine if they meet the bonus threshold:
      totalScores = sum(playerScores, 2); % Initialize array for total scores
      for p = 1:numberOfPlayers
      upperSectionScore = sum(playerScores(p, upperSectionIndices));
      if upperSectionScore >= upperSectionBonusThreshold
      totalScores(p) += upperSectionBonusPoints;
      fprintf(‘Player %d receives an upper section bonus of %d points!\n’, p, upperSectionBonusPoints);
      end
      end

      This loop not only calculates the bonus but also provides feedback to the player, enhancing the game’s interactivity and clarity.

  2. Displaying Final Scores:
    • Displaying final scores in a clear and understandable manner was crucial. The code effectively communicates the final scores to the players:
      fprintf(‘Final Scores (including any Upper Section bonuses):\n’);
      for p = 1:numberOfPlayers
      fprintf(‘Player %d: %d\n’, p, totalScores(p));
      end

      This section of the code iterates through each player, displaying their total score, including any bonuses. This transparency in scoring helps maintain fairness and keeps players informed of their standings.

  3. Determining the Winner(s):
    • One of the more complex challenges was handling the determination of the winner, especially in tie situations. The code first identifies the highest score and then finds all players who have achieved this score:
      maxScore = max(totalScores); % Find the highest score
      winners = find(totalScores == maxScore); % Find all players with the highest score

      This approach ensures that all potential winners are identified, not just the first player to reach the highest score.

    • In the event of a tie, the code constructs a string listing all winning players and displays a congratulatory message:
      if length(winners) == 1
      fprintf(‘The winner is Player %d with a score of %d!\n’, winners, maxScore);
      else
      winningPlayersStr = num2str(winners(1));
      for i = 2:length(winners)
      winningPlayersStr = [winningPlayersStr, ‘, ‘, num2str(winners(i))];
      end
      fprintf(‘We have a tie! The winners are Players %s with a score of %d!\n’, winningPlayersStr, maxScore);
      end

      This part of the code not only announces the winner(s) but also handles the scenario of multiple winners gracefully, ensuring that all players who tied with the highest score are acknowledged.

By addressing these challenges through detailed and thoughtful coding, the game ensures accurate scoring, clear communication of final results, and fair determination of the winner(s), enhancing the overall gameplay experience and maintaining the integrity of the Yahtzee game.

(5). Optimizing Game Mechanics: The Role of Helper Functions in Yahtzee’s MATLAB Code

The Yahtzee game’s MATLAB code includes four helper functions that play a crucial role in the game’s mechanics. These functions are designed to address specific challenges and enhance the gameplay experience. Let’s discuss each of these helper functions in detail:

  1. isFullHouse Function:
    • Challenge: Determining whether a player’s dice roll constitutes a ‘Full House’ (a combination of three of a kind and a pair) is not straightforward and requires checking the dice for specific patterns.
    • Solution: The ‘isFullHouse’ function was written to automate this check. It counts the occurrences of each dice number and then verifies if there are exactly two different numbers, with one occurring three times and the other twice. This function simplifies the scoring process for the Full House category, ensuring accuracy and efficiency.
  2. isSmallStraight Function:
    • Challenge: Identifying a ‘Small Straight’ (four sequential dice numbers) involves checking for a sequence in the dice roll, which can be complex due to the various combinations possible.
    • Solution: The ‘isSmallStraight’ function addresses this by first sorting the dice rolls and then checking for a sequence of four consecutive numbers. This function streamlines the process of validating a Small Straight, making the scoring process more straightforward and less error-prone.
  3. isLargeStraight Function:
    • Challenge: Similar to the Small Straight, determining a ‘Large Straight’ (five sequential dice numbers) requires checking for a longer sequence, which adds complexity.
    • Solution: The ‘isLargeStraight’ function overcomes this by sorting the dice rolls and ensuring that each consecutive number differs by exactly one. This function ensures that Large Straights are accurately identified, contributing to the fairness and challenge of the game.
  4. isYahtzee Function:
    • Challenge: A ‘Yahtzee’ (all five dice showing the same number) is a rare and high-scoring category that needs precise validation to ensure no scoring errors.
    • Solution: The ‘isYahtzee’ function is designed to check if all dice have the same number. It simplifies the process of confirming a Yahtzee, a crucial aspect of the game, and ensures that players are rewarded appropriately for this challenging achievement.

Each of these helper functions is tailored to address specific complexities within the game’s scoring system. By abstracting these checks into separate functions, the main game code remains cleaner and more manageable, while also ensuring that the scoring is accurate and consistent with the rules of Yahtzee. These functions exemplify the effective use of modular programming in game development, enhancing both the reliability and maintainability of the code.

 

For Blackjack Dawg

Initial Development:

Initial development went smoothly. The first step was creating a structure for how the code was to be written. We did this by splitting the game into steps that needed to be done, then we organized these steps into a flow chart to show how the logic fits together. We then broke the steps into functions and loops and allocated these structures to team members.

The planning stage took two days. After planning we began coding. The coding step was fairly trouble free, except for a couple of bugs and integration. While we ran into bugs, all were solved quickly using google and the output from matlab’s built-in compiler. Integration was challenging, because the process and functions that we originally designed had to interact more with other functions than expected. This meant that more function parameters and variables had to be passed around, which also caused bugs and meant that more time had to spent modifying existing code. While integration took a couple of hours, we were still able to complete our programming before our set deadline, which was two days before our oral examination.

Testing:

Our testing phase involved playing the game to completion, and testing every possible scenario. Some of the scenarios we tested included the player busting, the player standing, loosing due to too few chips, and winning the game. We only ran into one bug while testing, and the bug had to do with a variable containing an incorrect value. Because of the bug, the player would loose when they had fewer than two chips, rather than when they had fewer than 10 chips as intended. While our testing phase was a success, our program might still contain bugs that only show up sometimes an event is triggered, perhaps bugs related to the speed at which the program is run. For this reason, further bug testing is required, or perhaps automated unit testing.

Code Refinement:

We made several changes to refine our code. The first change we made involved splitting one functions into two functions. This increased our codes readability, as it create two functions that were concise and easy to understand. Another change we made was replacing sections of code with shorter sections of code that have an identical function. In one instance an entire function (makeCardBacks) was able to be replaced with a single matrix operation. This makes our code faster and improves readability and maintainability. The final refinement we made had to do with formatting. Blank spaces were added as breaks in a couple of areas to denote a change of logic. Additionally, comments were added to describe what sections of the code do.