TicTacToe Program

So I was asked to design my Tic-Tac-Toe game again, and I got most of the way through it in about 5 hours. I kept making stupid errors that set me back half an hour or so, but I wanted to post it and get some critique on it.

The code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <windows.h>

// Some functions that are very long so I omitted them here

void DrawBoard(int board[], std::string players[]) {
   for (int i = 0; i < 9; i ++) {
      VP_GoToXY(37 + ((i % 3) * 2), 11 + ((i / 3) * 2));
      std::cout << ((board[i]) ? ((board[i] == 1) ? "X" : "O") : " ");
      if (i % 3 == 2) {
         if (i / 3 != 2) {
            VP_GoToXY(37, 12 + ((i / 3) * 2));
            std::cout << static_cast<char> (196)
                      << static_cast<char> (197)
                      << static_cast<char> (196)
                      << static_cast<char> (197)
                      << static_cast<char> (196);
         }
      }
      else
         std::cout << static_cast<char> (179);
   }
   VP_GoToXY(0, 12);
   std::cout << " " << players[0];
   VP_GoToXY(78 - players[1].length(), 12);
   std::cout << players[1];
}

void Move(int board[], std::string players[], int &player) {
   DrawBoard(board, players);
   VP_GoToXY(((player == 1) ? 0 : 78 - players[1].length()), 12);
   std::cout << "<" << players[player - 1] << ">";
   int position = 1;
   while (board[(position - 1)])
      position ++;
   int keyPress;
   do {
      VP_GoToXY(37 + (((position - 1) % 3) * 2), 11 + (((position - 1) / 3) * 2));
      std::cout << ((player == 1) ? "X" : "O");
      keyPress = VP_GetCh();
      VP_GoToXY(37 + (((position - 1) % 3) * 2), 11 + (((position - 1) / 3) * 2));
      std::cout << " ";
      do {
         if (keyPress == VK_RIGHT)
            position = ((position < 9) ? (position + 1) : 1);
         if (keyPress == VK_LEFT)
            position = ((position > 1) ? (position - 1) : 9);
         if (keyPress == VK_DOWN) {
            position = ((position < 9) ? (position + 3) : 1);
            if (position > 9)
               position = position - 9 + 1;
         }
         if (keyPress == VK_UP) {
            position = ((position > 1) ? (position - 3) : 9);
            if (position < 1)
               position = position + 9 - 1;
         }
      } while (board[(position - 1)]);
   } while (keyPress != VK_RETURN);
   board[(position - 1)] = player;
   VP_GoToXY(((player == 1) ? 0 : 78 - players[1].length()), 12);
   std::cout << " " << players[player - 1] << " ";
   player = ((player == 1) ? 2 : 1);
}

int Winner(int board[]) {
   for(int i = 0; i < 3; i ++)
      // Horizontal Victory
      if (board[(i * 3) + 0] == board[(i * 3) + 1]
       && board[(i * 3) + 1] == board[(i * 3) + 2])
         return board[(i * 3) + 0];

      // Vertical Victory
      else if (board[(0 * 3) + i] == board[(1 * 3) + i]
            && board[(1 * 3) + i] == board[(2 * 3) + i])
         return board[(0 * 3) + i];

   // Diagonal Victory
   if (board[0] == board[4] && board[4] == board[8])
      return board[0];
   if (board[2] == board[4] && board[4] == board[6])
      return board[2];
   // Draw
   int moves = 0;
   for (int i = 0; i < 9; i ++)
      if (board[i])
         moves ++;
   if (moves == 9)
      return 3;
   return 0;
}

void TicTacToe() {
   // Create game board
   int tttBoard[] = {
      0,0,0,
      0,0,0,
      0,0,0
   };
   // Create player
   int player = 1;
   // Create winner
   int winner;
   // Create player names
   std::string players[] = {
      "Player 1",
      "Player 2"
   };
   DrawBoard(tttBoard, players);
   do {
      Move(tttBoard, players, player);
   } while (!(winner = Winner(tttBoard)));

   VP_ClearScreen();
   DrawBoard(tttBoard, players);
   VP_GoToXY(26, 17);

   // Player won
   if (winner != 3)
      std::cout << players[(winner - 1)] << " won! Great Job!";
   // Draw
   else
      std::cout << "No one won! Game ended in a Draw!";
   std::cout << "\nPress any key to continue...";
   VP_GetCh();
}

int main() {
   VP_SetConsoleCursor(false);
   // Define Settings Menu
   //Menu SettingsMenu("Settings", "-> ", " <-", CENTER, CENTER);
   // Define Main Menu
   Menu MainMenu("Tic-Tac-Toe", "-> ", " <-", CENTER, CENTER);
   MainMenu.AddOption("Play Tic-Tac-Toe", TicTacToe);
   //MainMenu.AddOption("Settings", std::bind(&Menu::Play, std::ref(SettingsMenu)));
   MainMenu.AddOption("Exit");

   MainMenu.Play();

   return 0;
}


It's not perfect, and by no means is it standard, but I'm still working towards getting Linux set up on my Desktop so I can test so more of my functions and make them more portable.

The complete compilable code is here:
http://pastebin.com/N0DLyBEj

It does have Functional used in it, which is a C++11 feature. To remove it, remove the Menu class and alter the main function as well.
i am a windows user, but your code looks okay..
perhaps you could add some other effects like beeps, colors..
and perhaps you could make the board better..
closed account (o1vk4iN6)

Why not just use a character instead ?

1
2
3
cout << static_cast<char> (196);

cout << '\xC4' ;
Why not just use a character instead ?


I didn't think about that. I keep forgetting I can put the actual values in and have them displayed. I'm only used to using delimiters for returns, tabs, etc.

@homi
There is only so much I can do on a console. Adding beeps is annoying, at least in my opinion. I do want to tighten up the display more. But all of that will come when I convert this into a class. I know it defeats the purpose of a class, but it's easier to work with.
Topic archived. No new replies allowed.