#include //Adapted from http://www.cppgameprogramming.com/cgi/nav.cgi?page=tictactoe BITMAP *imgPlayerOne; BITMAP *imgPlayerTwo; const signed short int PLAYER_ONE = -1, PLAYER_TWO = 1, EMPTY = 0; const signed short int PIECE_WIDTH = 200, PIECE_HEIGHT = 150; signed short int board[3][3]; unsigned short int currentRow = 0, currentColumn = 0, numMoves = 0; signed short int currentPlayer = PLAYER_ONE; bool gameActive = false; int x = 0, y = 0, lastX = 0, lastY = 0; void clearSelect (); void drawBoard (); void drawPiece (int player); void drawSelect (); bool hasWon (int player); void gameEnd (int winner); void move (); void reset (); void switchPlayer (); void updateBoard (); void clearSelect () { rect(screen, lastX+1, lastY+1, lastX + (PIECE_WIDTH - 1), lastY + (PIECE_HEIGHT - 1), makecol(0, 0, 0)); } void drawBoard () { acquire_screen(); rectfill(screen, 0, 0, (3 * PIECE_WIDTH), (3 * PIECE_HEIGHT), makecol(0, 0, 0)); for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { rect(screen, (row * PIECE_WIDTH), (col * PIECE_HEIGHT), ((row + 1) * PIECE_WIDTH), ((col + 1) * PIECE_HEIGHT), makecol(255, 255, 255)); } } drawSelect(); release_screen(); } void drawPiece (int player) { if (player == PLAYER_ONE) { draw_sprite(screen, imgPlayerOne, x, y); } else { draw_sprite(screen, imgPlayerTwo, x, y); } } void drawSelect () { rect(screen, x+1, y+1, x + (PIECE_WIDTH - 1), y + (PIECE_HEIGHT - 1), makecol(255, 255, 0)); } bool hasWon (int player) { if (numMoves < 3) { return false; } //Check both digs if (board[1][1] == player && ((board[0][0] == player && board[2][2] == player) || (board[0][2] == player && board[2][0] == player))) { return true; } for (int col = 0; col < 3; col++) { if (board[0][col] == player && board[1][col] == player && board[2][col] == player) { return true; } } for (int row = 0; row < 3; row++) { if (board[row][0] == player && board[row][1] == player && board[row][2] == player) { return true; } } return false; } void gameEnd (int winner) { if (winner == PLAYER_ONE) { textout_ex(screen, font, "Player One Wins", 300, 240, makecol(255, 0, 0), makecol(0, 0, 0)); } else if (winner == PLAYER_TWO) { textout_ex(screen, font, "Player Two Wins", 300, 240, makecol(255, 0, 0), makecol(0, 0, 0)); } else { textout_ex(screen, font, "Draw", 300, 240, makecol(255, 0, 0), makecol(0, 0, 0)); } switchPlayer(); gameActive = false; } void move () { clear_keybuf(); if (!gameActive) { if (key[KEY_ENTER]) { reset(); } } else { lastX = x; lastY = y; if (key[KEY_UP] && currentRow > 0) { y -= 150; currentRow--; updateBoard(); } else if (key[KEY_DOWN] && currentRow < 2) { y += 150; currentRow++; updateBoard(); } else if (key[KEY_RIGHT] && currentColumn < 2) { x += 200; currentColumn++; updateBoard(); } else if (key[KEY_LEFT] && currentColumn > 0) { x -= 200; currentColumn--; updateBoard(); } else if (key[KEY_ENTER] && board[currentRow][currentColumn] == EMPTY) { acquire_screen(); drawPiece(currentPlayer); board[currentRow][currentColumn] = currentPlayer; numMoves++; if (hasWon(currentPlayer)) { gameEnd(currentPlayer); } else if (numMoves >= 9) { gameEnd(EMPTY); } else { switchPlayer(); } release_screen(); } } rest(100); } void reset () { for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { board[row][col] = EMPTY; } } drawBoard(); numMoves = 0; gameActive = true; } void switchPlayer () { if (currentPlayer == PLAYER_ONE) { currentPlayer = PLAYER_TWO; } else { currentPlayer = PLAYER_ONE; } } void updateBoard () { acquire_screen(); clearSelect(); drawSelect(); release_screen(); } int main () { allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, (3 * PIECE_WIDTH), (3 * PIECE_HEIGHT), 0, 0); imgPlayerOne = load_bitmap("x.bmp", NULL); imgPlayerTwo = load_bitmap("o.bmp", NULL); if (!(imgPlayerOne && imgPlayerTwo)) { alert("Could not load images \"x.bmp\" and \"o.bmp\"", "These should be placed in the same folder as the executable", "This programme will now terminate", "Ok", NULL, 'o', 0); } else { reset(); while(!key[KEY_ESC]) { move(); } } destroy_bitmap(imgPlayerOne); destroy_bitmap(imgPlayerTwo); return 0; } END_OF_MAIN();