Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*-------------------------------------------------------------------------
- Include files:
- -------------------------------------------------------------------------*/
- #include <stdio.h>
- /*-------------------------------------------------------------------------
- Constants and definitions:
- -------------------------------------------------------------------------*/
- #define N 11
- #define MIN_SIZE 1
- #define MAX_MOVES N*N + 1
- #define COORDS 2
- #define ROW_CORD 0
- #define COL_CORD 1
- #define PLAYER_OFFSET 1
- #define CORD_OFFSET 1
- #define EMPTY_CELL '_'
- #define X_CELL 'X'
- #define O_CELL 'O'
- #define EVEN_TEST 2
- #define ERROR 2
- /*-------------------------------------------------------------------------
- Function declaration
- -------------------------------------------------------------------------*/
- void print_welcome();
- void print_enter_board_size();
- void print_board(char board[N][N], int n);
- void print_player_turn(int player_index);
- int print_error();
- int print_winner(int player_index);
- void print_tie();
- void SetBoard(char Board[N][N], char Symbol);
- int isMove(int Row, int Column, unsigned int TableSize, char Board[N][N]);
- int isWinner(char Board[N][N], unsigned int TableSize);
- int PlayerMove(char Board[N][N], unsigned MoveList[MAX_MOVES][COORDS], unsigned int TableSize, unsigned* pTurn, int* MoveNum);
- int StartGame(char Board[N][N], unsigned* pTurn, int TableSize);
- int Undo(int Rollback, unsigned MoveList[MAX_MOVES][COORDS], char Board[N][N], unsigned int TableSize, unsigned* pTurn, int* MoveNum);
- int CheckDiagonal(char Board[N][N], unsigned int TableSize);
- /*-------------------------------------------------------------------------
- Implementation
- -------------------------------------------------------------------------*/
- //11 lines
- int main()
- {
- unsigned int TableSize, pTurn = 0;
- char Board[N][N];
- print_welcome();
- print_enter_board_size();
- scanf("%u", &TableSize);
- SetBoard(Board, EMPTY_CELL);
- print_board(Board, TableSize);
- if (StartGame(Board, &pTurn, TableSize) < (int)(TableSize * TableSize)) return print_winner((int)(!pTurn + PLAYER_OFFSET));
- if (pTurn == MIN_SIZE) return print_winner((int)(pTurn + PLAYER_OFFSET));
- print_tie();
- return 0;
- }
- //Starts the game and continues it until a winner is decided, and then returns the number of moves it tooks
- //7 lines
- int StartGame(char Board[N][N], unsigned* pTurn, int TableSize)
- {
- int MoveNum = 0, GameOver = 0;
- unsigned MoveList[MAX_MOVES][COORDS] = { {0} };
- while ((!GameOver || GameOver == ERROR) && MoveNum != TableSize*TableSize)
- {
- if(GameOver != ERROR) print_player_turn(*pTurn + PLAYER_OFFSET);
- GameOver = PlayerMove(Board, MoveList, TableSize, pTurn, &MoveNum);
- if(GameOver != ERROR) print_board(Board, TableSize);
- }
- return MoveNum;
- }
- //Calculates the player's move and updates it into the board's array
- //13 lines
- int PlayerMove(char Board[N][N], unsigned MoveList[MAX_MOVES][COORDS], unsigned int TableSize, unsigned* pTurn, int* MoveNum)
- {
- int Row, Column, returnval = 0;
- scanf(" %d", &Row);
- if (Row >= 0)
- {
- if (scanf(" %d", &Column) && isMove(Row, Column, TableSize, Board))
- {
- Board[Row-CORD_OFFSET][Column-CORD_OFFSET] = *pTurn ? O_CELL : X_CELL;
- if (isWinner(Board, TableSize)) return 1;
- *MoveNum += 1;
- MoveList[*MoveNum - CORD_OFFSET][ROW_CORD] = Row - CORD_OFFSET;
- MoveList[*MoveNum - CORD_OFFSET][COL_CORD] = Column - CORD_OFFSET;
- *pTurn = !*pTurn;
- }
- else return print_error();
- }
- else returnval = Undo(Row, MoveList, Board, TableSize, pTurn, MoveNum);
- return returnval;
- }
- //Checks if the move is legal or not
- //7 lines
- int isMove(int Row, int Column, unsigned int TableSize, char Board[N][N])
- {
- if (Row > 0) //Regular
- {
- if ((Row > (int)TableSize) || (Column > (int)TableSize)) return 0;
- if (Board[Row - CORD_OFFSET][Column - CORD_OFFSET] != EMPTY_CELL) return 0;
- }
- else if (Row < 0) //Undo
- {
- if (!((-Row) % EVEN_TEST)) return 0;
- }
- else return 0;
- return 1;
- }
- //Rolls back a set odd-number of turns and then passes the turn on
- //9 lines
- int Undo(int Rollback, unsigned MoveList[MAX_MOVES][COORDS], char Board[N][N], unsigned int TableSize, unsigned* pTurn, int* MoveNum)
- {
- if (!isMove(Rollback, Rollback, TableSize, Board)) return print_error();
- if (-Rollback > (int)*MoveNum) return print_error();
- for (int i = 0; i < (-Rollback); i++)
- {
- Board[MoveList[*MoveNum - CORD_OFFSET - i][ROW_CORD]][MoveList[*MoveNum - CORD_OFFSET - i][COL_CORD]] = EMPTY_CELL;
- MoveList[*MoveNum - CORD_OFFSET - i][ROW_CORD] = 0;
- MoveList[*MoveNum - CORD_OFFSET - i][COL_CORD] = 0;
- }
- *MoveNum += Rollback;
- *pTurn = !*pTurn;
- return 0;
- }
- //Checks if there is a winning(or actually losing?) combination in the rows and lines of the board
- //9 lines
- int isWinner(char Board[N][N], unsigned int TableSize)
- {
- for (unsigned i = 0; i < TableSize; i++)
- for (unsigned j = 0; j < TableSize-1; j++)
- {
- if (Board[i][j] != Board[i][j + CORD_OFFSET] || Board[i][j] == EMPTY_CELL) break;
- if ((j == TableSize - 2) && Board[i][j] == Board[i][j + CORD_OFFSET]) return 1;
- }
- for (unsigned i = 0; i < TableSize; i++)
- for (unsigned j = 0; j < TableSize; j++)
- {
- if (Board[j][i] != Board[j + CORD_OFFSET][i] || Board[j][i] == EMPTY_CELL) break;
- if ((j == TableSize - 2) && Board[j][i] == Board[j + CORD_OFFSET][i]) return 1;
- }
- return CheckDiagonal(Board, TableSize);
- }
- //Like isWinner, checks for a winning combination in the two diagonals
- //7 lines
- int CheckDiagonal(char Board[N][N], unsigned int TableSize)
- {
- for (unsigned i = 0; i < TableSize - 1; i++)
- {
- if (Board[i][i] != Board[i + CORD_OFFSET][i + CORD_OFFSET] || Board[i][i] == EMPTY_CELL) break;
- if ((i == TableSize - 2) && Board[i][i] == Board[i + CORD_OFFSET][i + CORD_OFFSET]) return 1;
- }
- for (unsigned i = 0, j = TableSize-1; i < TableSize - 1; i++, j--)
- {
- if (Board[i][j] != Board[i + CORD_OFFSET][j - CORD_OFFSET] || Board[i][j] == EMPTY_CELL) break;
- if ((i == TableSize - 2) && Board[i][j] == Board[i + CORD_OFFSET][j - CORD_OFFSET]) return 1;
- }
- return 0;
- }
- //Initializes a board array to a chosen symbol, practically to '_'
- //3 lines
- void SetBoard(char Board[N][N], char Symbol)
- {
- for (int i = 0; i < N; i++)
- for (int j = 0; j < N; j++)
- Board[i][j] = Symbol;
- }
- //print welcome message
- //1 lines
- void print_welcome()
- {
- printf("*** Welcome to AVOIDANCE TIC-TAC-TOE game ***\n\n");
- }
- //print message to enter board size
- //1 lines
- void print_enter_board_size()
- {
- printf("Please enter board size (1 to %d):\n", N);
- }
- //print the board
- //7 lines
- void print_board(char board[N][N], int n)
- {
- printf("\nCurrent board:\n");
- for (int i = 0; i < n; i++)
- {
- printf("|");
- for (int j = 0; j < n; j++)
- {
- printf("%c|", board[i][j]);
- }
- printf("\n");
- }
- printf("\n");
- }
- //print a request for player with index "player_index" to move
- //1 lines
- void print_player_turn(int player_index)
- {
- printf("\nPlayer ** %d **, enter next move:\n", player_index);
- }
- //print error message
- //1 lines
- int print_error()
- {
- printf("Illegal move!!!, please try again:\n");
- return ERROR;
- }
- //print the winner
- //1 lines
- int print_winner(int player_index)
- {
- return printf("Player %d Wins! Hooray!\n", player_index);
- }
- //print message to announce there is a tie (no one wins)
- //1 lines
- void print_tie()
- {
- printf("It's a tie!\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement