Skip to content

Commit b32fd81

Browse files
Merge pull request #4 from dzianis-sudkou/issue-2/computer-opponent
Computer Opponent
2 parents b2c370d + 8f3a92f commit b32fd81

File tree

4 files changed

+179
-151
lines changed

4 files changed

+179
-151
lines changed

src/Generate.effekt

Lines changed: 101 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@ def generateNewBigBoard(): BigBoards = {
1616
BigBoards(bigBoard, smallBoard)
1717
}
1818

19-
def newActiveSmallBoard(bigBoards: BigBoards, number: Int): BigBoards = {
19+
20+
// Makes a new Small Board Active()
21+
def newActiveSmallBoard(gameBoard: BigBoards, smallBoardNumber: Int): BigBoards = {
2022
with on[OutOfBounds].panic
2123

22-
var newBigBoard: BigBoard = bigBoards.bigBoard
23-
var newBigBoardSmallCopy: SmallBoard = bigBoards.smallCopy
24-
var newSmallBoard: SmallBoard = newBigBoard.get(number - 1)
24+
var newBigBoard: BigBoard = gameBoard.bigBoard
25+
var newGameBoardSmallCopy: SmallBoard = gameBoard.smallCopy
26+
var newSmallBoard: SmallBoard = newBigBoard.get(smallBoardNumber )
2527

2628

2729
// Making Active Cell in the Small Copy of the Big Board
28-
newBigBoardSmallCopy = newBigBoardSmallCopy.replace(number - 1, Active())
30+
newGameBoardSmallCopy = newGameBoardSmallCopy.replace(smallBoardNumber, Active())
2931

3032
// Replacing all the Empty() cells with Active()
3133
var counter: Int = 0
@@ -38,17 +40,17 @@ def newActiveSmallBoard(bigBoards: BigBoards, number: Int): BigBoards = {
3840
()
3941
}
4042

41-
newBigBoard = newBigBoard.replace(number - 1, newSmallBoard)
42-
BigBoards(newBigBoard, newBigBoardSmallCopy)
43+
newBigBoard = newBigBoard.replace(smallBoardNumber, newSmallBoard)
44+
BigBoards(newBigBoard, newGameBoardSmallCopy)
4345
}
4446

45-
def deactivateSmallBoard(bigBoards: BigBoards, number: Int): BigBoards = {
47+
def deactivateSmallBoard(gameBoard: BigBoards, smallBoardNumber: Int): BigBoards = {
4648
with on[OutOfBounds].panic
4749

48-
var newBigBoard: BigBoard = bigBoards.bigBoard
49-
var newBigBoardSmallCopy: SmallBoard = bigBoards.smallCopy
50+
var newBigBoard: BigBoard = gameBoard.bigBoard
51+
var newGameBoardSmallCopy: SmallBoard = gameBoard.smallCopy
5052

51-
var newSmallBoard: SmallBoard = newBigBoard.get(number - 1)
53+
var newSmallBoard: SmallBoard = newBigBoard.get(smallBoardNumber)
5254
var counter: Int = 0
5355

5456

@@ -60,56 +62,37 @@ def deactivateSmallBoard(bigBoards: BigBoards, number: Int): BigBoards = {
6062
counter = counter + 1
6163
()
6264
}
63-
newBigBoard = newBigBoard.replace(number - 1, newSmallBoard)
64-
BigBoards(newBigBoard, newBigBoardSmallCopy)
65+
newBigBoard = newBigBoard.replace(smallBoardNumber, newSmallBoard)
66+
BigBoards(newBigBoard, newGameBoardSmallCopy)
6567
}
6668

67-
def checkNewCell(bigBoards: BigBoards, smallBoardNumber: Int, cellNumber: Int, player: Cell): BigBoards = {
69+
def checkNewCell(gameBoard: BigBoards, smallBoardNumber: Int, cellNumber: Int, player: Cell): BigBoards = {
6870
with on[OutOfBounds].panic
6971

70-
var newBigBoard: BigBoard = bigBoards.bigBoard
71-
var newSmallBoard: SmallBoard = newBigBoard.get(smallBoardNumber - 1)
72-
newSmallBoard = newSmallBoard.replace(cellNumber - 1, player)
73-
newBigBoard = newBigBoard.replace(smallBoardNumber - 1, newSmallBoard)
74-
BigBoards(newBigBoard, bigBoards.smallCopy)
72+
var newBigBoard: BigBoard = gameBoard.bigBoard
73+
var newSmallBoard: SmallBoard = newBigBoard.get(smallBoardNumber)
74+
newSmallBoard = newSmallBoard.replace(cellNumber, player)
75+
newBigBoard = newBigBoard.replace(smallBoardNumber, newSmallBoard)
76+
BigBoards(newBigBoard, gameBoard.smallCopy)
7577
}
7678

7779
/*
78-
* Returns true if the Small Board is free.
80+
* Returns true if the cell is free.
7981
* False Otherwise
8082
* Input : BigBoards, SmallBoardNumber, Cell Number
8183
* Output : Boolean
8284
*/
83-
def checkAvailableSmallBoard(bigBoards: BigBoards, cellNumber: Int): Bool = {
84-
with console
85+
def checkAvailableCell(smallBoard: SmallBoard, cellNumber: Int): Bool = {
8586
with on[OutOfBounds].panic
8687

87-
val cellType: Cell = bigBoards.smallCopy.get(cellNumber - 1)
88-
89-
cellType match {
88+
val cellType: Cell = smallBoard.get(cellNumber)
89+
cellType match {
9090
case Empty() => true
9191
case Active() => true
9292
case _ => false
9393
}
9494
}
9595

96-
97-
/*
98-
* Returns true if the cell is free.
99-
* False Otherwise
100-
* Input : BigBoards, SmallBoardNumber, Cell Number
101-
* Output : Boolean
102-
*/
103-
def checkAvailableCell(bigBoards: BigBoards, smallBoardNumber: Int, cellNumber: Int): Bool = {
104-
with on[OutOfBounds].panic
105-
106-
var newBigBoard: BigBoard = bigBoards.bigBoard
107-
var newSmallBoard: SmallBoard = newBigBoard.get(smallBoardNumber - 1)
108-
val cellType: Cell = newSmallBoard.get(cellNumber - 1)
109-
if (cellType is Active()) true
110-
else false
111-
}
112-
11396
/*
11497
* Returns true if Current Player has won in this Small Board.
11598
* False Otherwise
@@ -159,11 +142,81 @@ def checkWinSituation(smallBoard: SmallBoard, player: Cell): WinBoard = {
159142
win
160143
}
161144

162-
def fillWinningGameBoard(bigBoards: BigBoards, smallBoardNumber: Int, player: Cell): BigBoards = {
163-
var newBigBoard: BigBoard = bigBoards.bigBoard
164-
var newBigBoardSmallCopy: SmallBoard = bigBoards.smallCopy
145+
def fillWinningGameBoard(gameBoard: BigBoards, smallBoardNumber: Int, player: Cell): BigBoards = {
146+
var newBigBoard: BigBoard = gameBoard.bigBoard
147+
var newGameBoardSmallCopy: SmallBoard = gameBoard.smallCopy
148+
149+
newBigBoard = newBigBoard.replace(smallBoardNumber, fill(9, player))
150+
newGameBoardSmallCopy = newGameBoardSmallCopy.replace(smallBoardNumber, player)
151+
BigBoards(newBigBoard, newGameBoardSmallCopy)
152+
}
153+
154+
def computerPlay(smallBoard: SmallBoard, computer: Cell): Int = {
155+
println("It's computer playing. Please press Enter")
156+
consoleInput()
157+
with on[OutOfBounds].panic
158+
159+
var newSmallBoard: SmallBoard = smallBoard
160+
var player: Cell = Cross()
161+
if (computer is Cross()) player = Nought()
162+
var counter: Int = 0
163+
var resultCell: Int = 10
164+
165+
// Check for a winning move
166+
while (counter < 9 && resultCell == 10){
167+
if (checkAvailableCell(newSmallBoard, counter)){
168+
newSmallBoard = newSmallBoard.replace(counter, computer) // Simulate Computer's move
169+
if (checkWinSituation(newSmallBoard, computer) is Win()){
170+
resultCell = counter
171+
}else{
172+
newSmallBoard = newSmallBoard.replace(counter, Active())
173+
}
174+
}
175+
counter = counter + 1
176+
}
177+
178+
counter = 0
179+
// Check for a blocking move
180+
while (counter < 9 && resultCell == 10){
181+
if (checkAvailableCell(newSmallBoard, counter)){
182+
newSmallBoard = newSmallBoard.replace(counter, player) // // Simulate Player's move
183+
if (checkWinSituation(newSmallBoard, player) is Win()){
184+
resultCell = counter
185+
}else{
186+
newSmallBoard = newSmallBoard.replace(counter, Active())
187+
}
188+
}
189+
counter = counter + 1
190+
}
191+
192+
counter = 0
193+
// Choose center if available (strong strategically)
194+
if ((checkAvailableCell(newSmallBoard, 4)) && resultCell == 10){
195+
resultCell = 4
196+
}
197+
198+
counter = 0
199+
// Choose a corner if available
200+
[0,2,6,8].foreach { cellPos =>
201+
if ((checkAvailableCell(newSmallBoard, cellPos)) && resultCell == 10){
202+
resultCell = cellPos
203+
}
204+
}
205+
206+
// Choose any available side
207+
[1, 3, 5, 7].foreach { cellPos =>
208+
if ((checkAvailableCell(newSmallBoard, cellPos)) && resultCell == 10){
209+
resultCell = cellPos
210+
}
211+
}
212+
resultCell
213+
}
165214

166-
newBigBoard = newBigBoard.replace(smallBoardNumber - 1, fill(9, player))
167-
newBigBoardSmallCopy = newBigBoardSmallCopy.replace(smallBoardNumber - 1, player)
168-
BigBoards(newBigBoard, newBigBoardSmallCopy)
215+
def isComputerTurn(currentPlayer: Cell, computer: Cell): Bool = {
216+
var pcCross: Bool = false
217+
var returnValue: Bool = false
218+
if (computer is Cross()) pcCross = true
219+
if (currentPlayer is Cross() and pcCross) returnValue = true
220+
if (currentPlayer is Nought() and not(pcCross)) returnValue = true
221+
returnValue
169222
}

0 commit comments

Comments
 (0)