Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- testmain.cc************************************************************************************************************************
- /*
- This is a test main for the mancala class.
- If you are reading this, please close this
- text file, as I probably am doing dumb stuff
- in here.
- */
- #include <string>
- #include <queue>
- #include <iomanip>
- #include <iostream>
- #include "game.h"
- #include "mancala.h"
- using namespace main_savitch_14;
- int main ()
- {
- mancala m1;
- m1.display_status();
- return 0;
- std::cout<<"\n\n\n you shouldn't be reading this.";
- }
- mancala.cc************************************************************************************************************************
- This is the mancala class container for
- creating the main game implementation
- */
- #include <iostream>
- #include <queue>
- #include <string>
- #include <iomanip>
- #include <algorithm>
- #include "game.h"
- #include "colors.h"
- #include "mancala.h"
- using namespace main_savitch_14;
- void mancala::display_status()const
- {
- //Top Border
- for(int j = 0; j<5; j++)
- {
- for(int i = 0; i<40; i++)
- {
- cout<<B_YELLOW<<" ";
- }
- // cout<<RESET<<endl;
- }
- //West Border
- /*for(int j = 0; j<40; j++)
- {
- for(int i = 0; i<5; i++)
- {
- if(i % 5 || 6 == 0)
- {
- cout<<setw(4)<<B_BLACK<<" ";
- }
- else
- cout << B_YELLOW<<" ";
- //Middle Screen
- }
- for (int h = 0; h < 10; h++)
- {
- if (h % 5 || 6 == 0)
- {
- cout << setw(4) << B_BLACK << " ";
- }
- cout<<setw(4)<<B_YELLOW<<" ";
- }
- for(int i = 0; i<5; i++)
- {
- if(!(i % 10)&& i % 5 || 6 == 0)
- {
- cout<<setw(4)<<B_BLACK<<" ";
- }
- else
- cout << B_YELLOW<<" ";
- }
- }
- cout<<RESET<<endl;*/
- }
- mancala::mancala()
- {
- holes = 14;
- for(int i = 0; i < holes; i++)
- {
- if(i==0 || 7)
- {
- data [i] = 0;
- }
- else
- data [i] = 4;
- }
- }
- void mancala::mid_screen(int m)const
- {
- for(int i = 0; i<10; i++)
- {
- if(m % 10 != 0 && i % 5 || 6 == 0)
- {
- cout<<setw(4)<<B_BLACK<<WHITE<<" "<<data[i]<<" ";
- cout<<setw(4)<<B_BLACK<<" ";
- }
- else
- cout << B_YELLOW<<" ";
- cout << B_YELLOW<<" ";
- cout << B_YELLOW<<" ";
- }
- }
- void mancala::display_message(const std::string& message)const
- {
- }
- std::string mancala::get_user_move()const
- {
- }
- game::who mancala::last_mover()const
- {
- }
- int mancala::moves_completed()const
- {
- }
- game::who mancala::next_mover()const
- {
- }
- game::who mancala::opposite(game::who player)const
- {
- }
- game::who mancala::winning()const
- {
- }
- void mancala::make_move(const std::string& move)
- {
- }
- void mancala::restart()
- {
- }
- game* mancala::clone()const
- {
- }
- void mancala::compute_moves(std::queue<std::string>& moves)const
- {
- }
- int mancala::evaluate()const
- {
- }
- bool mancala::is_game_over()const
- {
- }
- bool mancala::is_legal(const std::string& move)const
- {
- }
- mancala.h************************************************************************************************************************
- This is the header file for all of the main mancala
- game functions.
- */
- #include <string>
- #include <queue>
- #include <iomanip>
- #include "game.h"
- using namespace main_savitch_14;
- class mancala:public game
- {
- int holes;
- int data[];
- public:
- mancala();
- void display_status()const;
- void mid_screen(int m)const;
- void display_message(const std::string& message)const;
- std::string get_user_move()const;
- who last_mover()const;
- int moves_completed()const;
- who next_mover()const;
- who opposite(who player)const;
- who winning()const;
- void make_move(const std::string& move);
- void restart();
- game* clone()const;
- void compute_moves(std::queue<std::string>& moves)const;
- int evaluate()const;
- bool is_game_over()const;
- bool is_legal(const std::string& move)const;
- };
- game.h************************************************************************************************************************
- // File: game.h (part of the namespace main_savitch_14)
- #ifndef MAIN_SAVITCH_GAME
- #define MAIN_SAVITCH_GAME
- #include <queue> // Provides queue<string>
- #include <string> // Provides string
- namespace main_savitch_14
- {
- class game
- {
- public:
- // ENUM TYPE
- enum who { HUMAN, NEUTRAL, COMPUTER }; // Possible game outcomes
- // CONSTRUCTOR and DESTRUCTOR
- game( ) { move_number = 0; }
- virtual ~game( ) { }
- // PUBLIC MEMBER FUNCTIONS
- // The play function should not be overridden. It plays one game,
- // with the human player moving first and the computer second.
- // The computer uses an alpha-beta look ahead algorithm to select its
- // moves. The return value is the winner of the game (or NEUTRAL for
- // a tie).
- who play( );
- protected:
- // *******************************************************************
- // OPTIONAL VIRTUAL FUNCTIONS (overriding these is optional)
- // *******************************************************************
- virtual void display_message(const std::string& message) const;
- virtual std::string get_user_move( ) const;
- virtual who last_mover( ) const
- { return (move_number % 2 == 1 ? HUMAN : COMPUTER); }
- virtual int moves_completed( ) const { return move_number; }
- virtual who next_mover( ) const
- { return (move_number % 2 == 0 ? HUMAN : COMPUTER); }
- virtual who opposite(who player) const
- { return (player == HUMAN) ? COMPUTER : HUMAN; }
- virtual who winning( ) const;
- // *******************************************************************
- // VIRTUAL FUNCTIONS THAT MUST BE OVERRIDDEND:
- // The overriding function should call the original when it finishes.
- // *******************************************************************
- // Have the next player make a specified move:
- virtual void make_move(const std::string& move) { ++move_number; }
- // Restart the game from the beginning:
- virtual void restart( ) { move_number = 0; }
- // *******************************************************************
- // PURE VIRTUAL FUNCTIONS
- // *******************************************************************
- // (these must be provided for each derived class)
- // Return a pointer to a copy of myself:
- virtual game* clone( ) const = 0;
- // Compute all the moves that the next player can make:
- virtual void compute_moves(std::queue<std::string>& moves) const = 0;
- // Display the status of the current game:
- virtual void display_status( ) const = 0;
- // Evaluate a board position:
- // NOTE: positive values are good for the computer.
- virtual int evaluate( ) const = 0;
- // Return true if the current game is finished:
- virtual bool is_game_over( ) const = 0;
- // Return true if the given move is legal for the next player:
- virtual bool is_legal(const std::string& move) const = 0;
- private:
- // MEMBER VARIABLES
- int move_number; // Number of moves made so far
- // STATIC MEMBER CONSTANT
- static const int SEARCH_LEVELS = 4; // Levels for look-ahead evaluation
- // PRIVATE FUNCTIONS (these are the same for every game)
- int eval_with_lookahead(int look_ahead, int beat_this);
- void make_computer_move( );
- void make_human_move( );
- };
- }
- #endif
- game.cc********************************************************************************************************************************
- // File: game.cxx
- #include <cassert> // Provides assert
- #include <climits> // Provides INT_MAX and INT_MIN
- #include <iostream> // Provides cin, cout
- #include <queue> // Provides queue<string>
- #include <string> // Provides string
- #include "game.h" // Provides definition of game class
- using namespace std;
- namespace main_savitch_14
- {
- //*************************************************************************
- // STATIC MEMBER CONSTANTS
- // const int game::SEARCH_LEVELS;
- //*************************************************************************
- // PUBLIC MEMBER FUNCTIONS
- game::who game::play( )
- // The play function should not be overridden. It plays one round of the
- // game, with the human player moving first and the computer second.
- // The return value is the winner of the game (or NEUTRAL for a tie).
- {
- restart( );
- // Note that as you develop the game you will be gradually un-commenting
- // this function.
- //while (!is_game_over( )) // un-comment this
- //{
- display_status( );
- // if (last_mover( ) == COMPUTER)
- make_human_move( );
- // else
- // make_computer_move( );
- //}
- display_status( );
- return HUMAN;
- }
- //*************************************************************************
- // OPTIONAL VIRTUAL FUNCTIONS (overriding these functions is optional)
- void game::display_message(const string& message) const
- {
- cout << message;
- }
- string game::get_user_move( ) const
- {
- string answer;
- display_message("Your move, please: ");
- getline(cin, answer);
- return answer;
- }
- game::who game::winning( ) const
- {
- int value = evaluate( ); // Evaluate based on move that was just made.
- if (value > 0)
- return last_mover( );
- else if (value < 0)
- return next_mover( );
- else
- return NEUTRAL;
- }
- //*************************************************************************
- // PRIVATE FUNCTIONS (these are the same for every game)
- int game::eval_with_lookahead(int look_ahead, int beat_this)
- // Evaluate a board position with lookahead.
- // --int look_aheads: How deep the lookahead should go to evaluate the move.
- // --int beat_this: Value of another move that we?re considering. If the
- // current board position can't beat this, then cut it short.
- // The return value is large if the position is good for the player who just
- // moved.
- {
- queue<string> moves; // All possible opponent moves
- int value; // Value of a board position after opponent moves
- int best_value; // Evaluation of best opponent move
- game* future; // Pointer to a future version of this game
- // Base case:
- if (look_ahead == 0 || is_game_over( ))
- {
- if (last_mover( ) == COMPUTER)
- return evaluate( );
- else
- return -evaluate( );
- }
- // Recursive case:
- // The level is above 0, so try all possible opponent moves. Keep the
- // value of the best of these moves from the opponent's perspective.
- compute_moves(moves);
- // assert(!moves.empty( ));
- best_value = INT_MIN;
- while (!moves.empty( ))
- {
- future = clone( );
- future->make_move(moves.front( ));
- value = future->eval_with_lookahead(look_ahead-1, best_value);
- delete future;
- if (value > best_value)
- {
- best_value = value;
- }
- moves.pop( );
- }
- // The value was calculated from the opponent's perspective.
- // The answer we return should be from player's perspective, so multiply times -1:
- return -best_value;
- }
- void game::make_computer_move( )
- {
- queue<string> moves;
- int value;
- int best_value;
- string best_move;
- game* future;
- // Compute all legal moves that the computer could make.
- compute_moves(moves);
- //assert(!moves.empty( ));
- // Evaluate each possible legal move, saving the index of the best
- // in best_index and saving its value in best_value.
- best_value = INT_MIN;
- while (!moves.empty( ))
- {
- future = clone( );
- future->make_move(moves.front( ));
- value = future->eval_with_lookahead(SEARCH_LEVELS, best_value);
- delete future;
- if (value >= best_value)
- {
- best_value = value;
- best_move = moves.front( );
- }
- moves.pop( );
- }
- // Make the best move.
- make_move(best_move);
- }
- void game::make_human_move( )
- {
- string move;
- move = get_user_move( );
- while (!is_legal(move))
- {
- display_message("Illegal move.\n");
- move = get_user_move( );
- }
- make_move(move);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement