-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBoardState.cs
143 lines (123 loc) · 3.05 KB
/
BoardState.cs
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
namespace TicTacToe;
public struct BoardState
{
public CellState this[int index]
{
get => _state[index];
set
{
_state[index] = value;
}
}
private readonly CellState[] _state = {
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
CellState.FREE,
};
public Player CurrentPlayer = Player.CROSS;
readonly int[] WIN_POSITIONS = {
0b100_100_100,
0b010_010_010,
0b001_001_001,
0b111_000_000,
0b000_111_000,
0b000_000_111,
0b100_010_001,
0b001_010_100,
};
public BoardState()
{
}
public enum Player
{
CROSS,
CIRCLE
}
public Nullable<Player> GetWinner()
{
foreach (var winPosition in WIN_POSITIONS)
{
if ((winPosition & BitwiseBoardState(CellState.CROSS)) == winPosition)
{
return Player.CROSS;
}
else if ((winPosition & BitwiseBoardState(CellState.CIRCLE)) == winPosition)
{
return Player.CIRCLE;
}
}
return null;
}
public bool GameEnded()
{
if (GetWinner() != null) return true;
for (int i = 0; i < 9; i++)
{
if (_state[i] == CellState.FREE) return false;
}
return true;
}
public int BitwiseBoardState(CellState type)
{
int board = 0;
foreach (var state in _state)
{
board <<= 1;
if (type == state)
board++;
}
return board;
}
public void Play(int cellIndex)
{
switch (CurrentPlayer)
{
case Player.CROSS:
_state[cellIndex] = CellState.CROSS;
CurrentPlayer = Player.CIRCLE;
break;
case Player.CIRCLE:
_state[cellIndex] = CellState.CIRCLE;
CurrentPlayer = Player.CROSS;
break;
}
}
public void PrettyPrint()
{
for (int i = 0; i < 3; i++)
{
string lineString = "|";
for (int j = 0; j < 3; j++)
{
switch (_state[i + (j * 3)])
{
case CellState.FREE:
lineString += " ";
break;
case CellState.CIRCLE:
lineString += "o";
break;
case CellState.CROSS:
lineString += "x";
break;
}
lineString += "|";
}
GD.Print(lineString);
GD.Print("-------");
}
}
public BoardState Clone()
{
BoardState boardState = new();
_state.CopyTo(boardState._state, 0);
boardState.CurrentPlayer = CurrentPlayer;
return boardState;
}
}