Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pente.h"
- using namespace std;
- //PARTNERED W/ KENNY $
- int score_black = 0; //Each piece captured adds +1 to score
- int score_white = 0;
- const int WIN_THRESHOLD = 10; //You win if you capture 10 pieces
- //Uppercases a string
- void uppercaseify(std::string &s) {
- for (char &c : s) c = toupper(c);
- }
- //Quits the program with an error message
- void die(const std::string &error = "INVALID INPUT!") {
- std::cout << error << std::endl;
- exit(EXIT_FAILURE);
- }
- //Return true if the current move (x,y) results in five in a row (or more)
- // in a horizontal, vertical, or diagonal direction.
- //Remember to BOUNDS CHECK - never go off the edge of the vector
- //It takes the state of the board, and the x and y coordinates of the last move
- bool check_for_win(const vector<vector<char>> &board, const int x, const int y) {
- //YOU
- const char player = board[y][x];
- int vertical = 1;//(|)
- int horizontal = 1;//(-)
- int diagonal1 = 1;//(\)
- int diagonal2 = 1;//(/)
- int i = 0;//vertical
- int ii = 0;//horizontal
- //check for vertical(|)
- for (i = x + 1; i < SIZE && board[y][i] == player; i++, vertical++); //Check down
- for (i = x - 1; i >= 0 && board[y][i] == player; i--, vertical++); //Check up
- if (vertical >= 5)return true;
- //check for horizontal(-)
- for (ii = y - 1; ii >= 0 && board[ii][x] == player; ii--, horizontal++); //Check left
- for (ii = y + 1; ii < SIZE && board[ii][x] == player && ii <= SIZE; ii++, horizontal++); //Check right
- if (horizontal >= 5) return true;
- //check for diagonal 1 (\)
- for (i = x - 1, ii = y - 1; i >= 0 && ii >= 0 && board[ii][i] == player; diagonal1 ++, i --, ii --); //up and left
- for (i = x + 1, ii = y + 1; i < SIZE && ii < SIZE && board[ii][i] == player; diagonal1 ++, i ++, ii ++); //down and right
- if (diagonal1 >= 5) return true;
- //check for diagonal 2(/)
- for (i = x - 1, ii = y + 1; i >= 0 && ii < SIZE && board[ii][i] == player; diagonal2 ++, i --, ii ++); //up and right
- for (i = x + 1, ii = y - 1; i < SIZE && ii >= 0 && board[ii][i] == player; diagonal2 ++, i ++, ii --); //up and left
- if (diagonal2 >= 5) return true;
- return false;
- }
- //This function looks to see if a capture has been made, and makes it if so.
- //A capture is when the new piece flanks exactly two opposing pieces with one of the same color
- //For example, if you have _BBW, and white moves into the blank: WBBW, this is a capture.
- // It turns into W__W, and white gets +2 added to its score. (All captures add +2 to score.)
- //You win if one side gets 10 points.
- //It takes the state of the board, and the x and y coordinates of the last move
- void capture(vector<vector<char>> &board, const int x, const int y) {
- //YOU
- /* const char player = board[y][x];
- int vertical = 1;//(|)
- int horizontal = 1;//(-)
- int diagonal1 = 1;//(\)
- int diagonal2 = 1;//(/)
- int i = 0;//vertical
- int ii = 0;//horizontal
- //vertical capture(|)
- for (i = x + 1; i < SIZE && board[y][i] == player; i++, vertical++); //Check down
- for (i = x - 1; i >= 0 && board[y][i] == player; i--, vertical++); //Check up
- if (vertical >= 5)return true;
- //horizontal capture(-)
- for (ii = y - 1; ii >= 0 && board[ii][x] == player; ii--, horizontal++); //Check left
- for (ii = y + 1; ii < SIZE && board[ii][x] == player && ii <= SIZE; ii++, horizontal++); //Check right
- if (horizontal >= 5) return true;
- //diagnol capture(\)
- for (i = x - 1, ii = y - 1; i >= 0 && ii >= 0 && board[ii][i] == player; diagonal1 ++, i --, ii --); //up and left
- for (i = x + 1, ii = y + 1; i < SIZE && ii < SIZE && board[ii][i] == player; diagonal1 ++, i ++, ii ++); //down and right
- if (diagonal1 >= 5) return true;
- //diagonal 2 capture(/)
- for (i = x - 1, ii = y + 1; i >= 0 && ii < SIZE && board[ii][i] == player; diagonal2 ++, i --, ii ++); //up and right
- for (i = x + 1, ii = y - 1; i < SIZE && ii >= 0 && board[ii][i] == player; diagonal2 ++, i ++, ii --); //up and left
- if (diagonal2 >= 5) return true;
- */ // return false;
- }
- //Return true iff every square is not OPEN
- bool check_for_draw(const vector<vector<char>> &board) {
- for (int y = 0; y < SIZE; y++) {
- for (int x = 0; x < SIZE; x++) {
- if (board[x][y] == OPEN) {
- return false;
- }
- }
- }
- return true;
- }
- void print_board(const vector<vector<char>> &board, const bool black) {
- cout << '^L';
- cout << "CURRENT TURN: " << (black ? "BLACK\n" : "WHITE\n");
- cout << "SCOREBOARD - WHITE: " << score_white << " BLACK: " << score_black << endl << endl;
- //Column headers
- cout << " ";
- for (int col = 0; col < SIZE; col++)
- cout << col / 10;
- cout << endl;
- cout << " ";
- for (int col = 0; col < SIZE; col++)
- cout << col % 10;
- cout << endl;
- for (int row = 0; row < SIZE; row++) {
- cout << setw(2) << row; //Print row headers
- for (int col = 0; col < SIZE; col++) {
- //cout << "row: " << row << " col: " << col << " is: ";
- cout << board.at(row).at(col);
- }
- cout << endl;
- }
- }
- //YOU: If you want extra credit, write these functions in ai1.cc and ai2.cc
- void ai1_move(const vector<vector<char>> &board, int &x, int &y);
- void ai2_move(const vector<vector<char>> &board, int &x, int &y);
- //Takes a board state in by const reference, returns into x and y the
- // coordinates the human player wants to make
- void human_move(const vector<vector<char>> &board, int &x, int &y) {
- bool first_try = true;
- while (true) {
- if (!first_try) cout << "Invalid move, try again.\n";
- first_try = false;
- cout << "Please enter a move (x y):\n";
- cin >> x >> y;
- if (!cin) { //Bad move, redo
- cin.clear(); //Clear error flag
- string temp;
- getline(cin, temp); //Pull offending string out of cin
- continue;
- }
- if (x < 0 || x >= SIZE || y < 0 || y >= SIZE) //Bad move, redo
- continue;
- if (board[y][x] != OPEN) //Bad move, redo
- continue;
- //Ok, x and y have been set, return
- return;
- }
- }
- //Sets the board back to factory defaults
- void reset_board(vector<vector<char>> &board) {
- for (int i = 0; i < SIZE; i++) {
- board.at(i).resize(0); //Clear existing row
- board.at(i).resize(SIZE, OPEN); //Set row to all OPEN spaces
- }
- board[SIZE / 2][SIZE / 2] = WHITE; //Starting move is always white in the middle
- }
- //Ends the game
- void win(const vector<vector<char>> &board, bool won, bool black = true, string reason = "") {
- print_board(board, black);
- if (!won) {
- cout << "DRAW!\n";
- exit(EXIT_SUCCESS);
- }
- if (reason != "")
- cout << reason << endl;
- cout << (black ? "BLACK" : "WHITE") << ", A WINNER IS YOU!\n";
- exit(EXIT_SUCCESS);
- }
- int main() {
- //Part 1 - Set up the board
- vector<vector<char>> board(SIZE); //19x0 until resized by reset_board
- reset_board(board);
- /* -----------------------------------------------------------------*/
- //Part 2 - Set up the Pseudorandom Number Generator (PNG)
- cout << "Enter random seed:\n"; //This gives deterministic AI behavior
- int seed = 0;
- cin >> seed;
- srand(seed);
- /* -----------------------------------------------------------------*/
- //Part 3 - Set up the players in the game
- //p1 and p2 are variables holding functions!! They get called to make a move for white / black
- //ai1 is a white player AI, ai2 is a black player AI
- auto p1 = ai1_move; //Set player 1 under AI control
- auto p2 = ai2_move; //Set player 2 under AI control
- cout << "How many human players? (Type \"0\", \"1\", or \"2\")\n";
- int players = 0;
- cin >> players;
- if (!cin || players < 0 || players > 2) die("Bad # of Players");
- if (players == 2) {
- p1 = human_move; //Set player 1 under human control
- p2 = human_move; //Set player 2 under human control
- } else if (players == 1) {
- while (true) {
- cout << "Do you want to be the white or black player? (Type \"white\" or \"black\")\n";
- string s;
- cin >> s;
- uppercaseify(s);
- if (s == "WHITE") {
- p1 = human_move; //Set player 1 under human control
- break;
- } else if (s == "BLACK") {
- p2 = human_move; //Set player 2 under human control
- break;
- }
- }
- }
- /* -----------------------------------------------------------------*/
- //Part 4 - Main loop
- bool black = true; //Black goes first, since white starts with a free move
- while (true) {
- //usleep(200000); //Small delay
- int x = 0, y = 0; //Holds the move returned by p1 and p2
- print_board(board, black);
- if (black)
- p2(board, x, y); //Returns x and y by reference
- else
- p1(board, x, y); //Returns x and y by reference
- //Sanity check the move returned by the player or AI
- if (x < 0 || x >= SIZE || y < 0 || y >= SIZE || board[y][x] != OPEN)
- win(board, true, !black, "INVALID MOVE!");
- //Make the move
- board[y][x] = (black ? BLACK : WHITE);
- //Check for capture
- capture(board, x, y);
- //Check for win by score after capture
- if (score_black >= WIN_THRESHOLD || score_white >= WIN_THRESHOLD)
- win(board, true, black, "WIN BY CAPTURE!");
- //Check for win by 5 in a row (or more)
- if (check_for_win(board, x, y))
- win(board, true, black, "WIN BY 5+ IN A ROW!");
- //Check for draw
- if (check_for_draw(board))
- win(board, false); //Draw
- //Change whose turn it is
- black = !black;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement