Skip to content

Instantly share code, notes, and snippets.

@andradei
Created November 17, 2015 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andradei/410e476ed6b57ed4af7e to your computer and use it in GitHub Desktop.
Save andradei/410e476ed6b57ed4af7e to your computer and use it in GitHub Desktop.
Tic-Tac-Toe in C++
//
// main.cpp
// Tic-Tac-Toe
//
// Created by Isaac Andrade on 9/2/13.
// Copyright (c) 2013 Isaac Andrade. All rights reserved.
//
#include <iostream>
#include <string>
#include <array>
using namespace std;
// Global variables - available in nay scope of this program
const int ROWS = 3;
const int COLUMNS = 3;
const char BS = ' ';
// Declare functions: function prototypes
int gameStatus (int, char[ROWS][COLUMNS]);
void drawBoard(char[ROWS][COLUMNS]);
/************************************************************
Function to translate user input into actual array positions
a1 = 0,0 a2 = 0,1 a3 = 0,2
b1 = 1,0 b2 = 1,1 b3 = 1,2
c1 = 2,0 c2 = 2,1 c3 = 2,2
*************************************************************/
void translateInput(string *p_position, int *p_x, int *p_y) {
string x = *p_position;
char row = x[0];
char column = x[1];
if (x.length() != 2) *p_position = "Invalid position, please try again.";
if (row == 'a') {
switch (column) {
case '1':
*p_x = 0;
*p_y = 0;
break;
case '2':
*p_x = 0;
*p_y = 1;
break;
case '3':
*p_x = 0;
*p_y = 2;
break;
default:
*p_position = "Invalid position, please try again.";
break;
}
}
else if (row == 'b') {
switch (column) {
case '1':
*p_x = 1;
*p_y = 0;
break;
case '2':
*p_x = 1;
*p_y = 1;
break;
case '3':
*p_x = 1;
*p_y = 2;
break;
default:
*p_position = "Invalid position, please try again.";
break;
}
}
else if (row == 'c') {
switch (column) {
case '1':
*p_x = 2;
*p_y = 0;;
break;
case '2':
*p_x = 2;
*p_y = 1;;
break;
case '3':
*p_x = 2;
*p_y = 2;
break;
default:
*p_position = "Invalid position, please try again.";
break;
}
}
else *p_position = "Invalid position, please try again.";
}
/***************************
MAIN
****************************/
int main()
{
// Variables
char marks[] = {'O', 'X'}; // O = 0, X = 1
int players[] = {2, 1}; // logic starts getting index 1, then it alternates until the end of program. See line 148
int round = 1;
int status = 0;
char playerGame[ROWS][COLUMNS] = {{BS,BS,BS},{BS,BS,BS},{BS,BS,BS}};
int x_cord, y_cord; // these receive values passed by reference through the translateInput() function
string position = "";
//Start the game loop
while (status == 0) {
// Draw the board with the current game
drawBoard(playerGame);
// Get user input and assess it
do {
cout << "Round " << round << endl;
cout << "Player " << players[round%2]<< ", enter a position:";
cin >> position;
translateInput(&position, &x_cord, &y_cord);
cout << position << endl;
} while (position.length() != 2);
// If input was valid, add it to the board
if (position.length() == 2) playerGame[x_cord][y_cord] = marks[round%2];
// Get ready for next round
round++;
// store game status
status = gameStatus(round, playerGame);
}
// Exit game properly - diplaying message to user
drawBoard(playerGame);
if (status == 1)
cout << "Player 1 won!" << endl;
else if (status == 2)
cout << "Player 2 won!" << endl;
else if (status == 3)
cout << "We have a draw!" << endl;
else
cout << "Match ended with invalid status." << endl;
// The End
return 0;
}
// Define functions declared up top
/***********************************
Function to check if the game ended
0 - Game is ongoing
1 - Player 1 won
2 - Player 2 won
3 - Draw
************************************/
int gameStatus (int round, char playerGame[ROWS][COLUMNS]) {
// true = someone won
bool status = ((playerGame[0][0] == playerGame[0][1]) && (playerGame[0][0] == playerGame[0][2]) && (playerGame[0][0] != BS)) || // 1st row
((playerGame[1][0] == playerGame[1][1]) && (playerGame[1][0] == playerGame[1][2]) && (playerGame[1][0] != BS)) || // 2nd row
((playerGame[2][0] == playerGame[2][1]) && (playerGame[2][0] == playerGame[2][2]) && (playerGame[2][0] != BS)) || // 3rd row
((playerGame[0][0] == playerGame[1][0]) && (playerGame[0][0] == playerGame[2][0]) && (playerGame[0][0] != BS)) || // 1st column
((playerGame[0][1] == playerGame[1][1]) && (playerGame[0][1] == playerGame[2][1]) && (playerGame[0][1] != BS)) || // 2nd column
((playerGame[0][2] == playerGame[1][2]) && (playerGame[0][2] == playerGame[2][2]) && (playerGame[0][2] != BS)) || // 3rd column
((playerGame[0][0] == playerGame[1][1]) && (playerGame[0][0] == playerGame[2][2]) && (playerGame[0][0] != BS)) || // diagonal '\'
((playerGame[0][2] == playerGame[1][1]) && (playerGame[0][2] == playerGame[2][0]) && (playerGame[0][2] != BS)); // diagonal '/'
if (round >= 5 && round < 9 && status) { // Someone won!
if (round % 2 != 0) return 2;
else return 1;
}
else if(!status && round == 9) return 3; // It is a draw!
else return 0; // Game is ongoing
}
/*********************************
Function that will draw the board
1 2 3 -> c
01234 -> j
a 0 | | \n
1 -----\n
b 2 | | \n
3 -----\n
c 4 | | \n
| |
| |-> i
|-> r
**********************************/
void drawBoard(char pG[ROWS][COLUMNS]) {
for (int i=0, r=0; i < ROWS+2; i++) {
if (i%2 != 0) {
cout << "-----\n";
} else {
for (int j=0, c=0; j < COLUMNS+2; j++) {
if (j%2 != 0) {
cout << "|";
} else {
cout << pG[r][c];
++c; // keep scanning the columns
if (j == 4) cout << endl; // carriage return in the end of every row
}
}
++r; // keep scanning the rows
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment