September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,12 +1,9 @@
|
|||
[[File:Tic_tac_toe.jpg|500px||right]]
|
||||
|
||||
;Task:
|
||||
Play a game of [[wp:Tic-tac-toe|tic-tac-toe]].
|
||||
Play a game of [[wp:Tic-tac-toe|tic-tac-toe]]. Ensure that legal moves are played and that a winning position is notified.
|
||||
|
||||
|
||||
Ensure that legal moves are played and that a winning position is notified.
|
||||
|
||||
|
||||
;See:
|
||||
* [[http://mathworld.wolfram.com/Tic-Tac-Toe.html Mathworld™, Tic-Tac-Toe game]].
|
||||
;See also
|
||||
* [http://mathworld.wolfram.com/Tic-Tac-Toe.html Mathworld™, Tic-Tac-Toe game].
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Games
|
||||
note: Games
|
||||
|
|
|
|||
31
Task/Tic-tac-toe/MIRC-Scripting-Language/tic-tac-toe.mirc
Normal file
31
Task/Tic-tac-toe/MIRC-Scripting-Language/tic-tac-toe.mirc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
alias ttt {
|
||||
if ($2 isin %ttt) || (!%ttt) {
|
||||
var %ttt~ = $remove($iif(%ttt,%ttt,1 2 3 4 5 6 7 8 9),$2,X,O)
|
||||
var %ttt~~ = $replace($iif(%ttt,%ttt,1 2 3 4 5 6 7 8 9),$2,X)
|
||||
set %ttt $replace(%ttt~~,$iif(($regex(%ttt~~,/(?:O . . (?:(?:. O .|O) . . (\d)|(?:. (\d) .|(\d)) . . O)|(\d) . . (?:. O .|O) . . O|. . (?:O . (?:O . (\d)|(\d) . O)|(\d) . O . O) . .)/)) || ($regex(%ttt~~,/^(?:. . . )*(?:O (?:O (\d)|(\d) O)|(\d) O O)(?: . . .)*$/)),$regml(1),$iif(($regex(%ttt~~,/(?:X . . (?:(?:. X .|X) . . (\d)|(?:. (\d) .|(\d)) . . X)|(\d) . . (?:. X .|X) . . X|. . (?:X . (?:X . (\d)|(\d) . X)|(\d) . X . X) . .)/)) || ($regex(%ttt~~,/^(?:. . . )*(?:X (?:X (\d)|(\d) X)|(\d) X X)(?: . . .)*$/)),$regml(1),$iif($remove(%ttt~,2,4,6,8,$chr(32)),$iif((5 isin $remove(%ttt~,2,4,6,8)) && ($rand(0,$numtok($v2,32)) == 0),5,$gettok($remove(%ttt~,2,4,6,8),$rand(1,$numtok($remove(%ttt~,2,4,6,8),32)),32)),$gettok(%ttt~,$rand(1,$numtok(%ttt~,32)),32)))),O)
|
||||
tokenize 32 %ttt
|
||||
if ($regex(%ttt,/(?:X . . (?:X|. X .) . . X|. . X . X . X . .)/)) || ($regex(%ttt,/^(?:. . . )*X X X(?: . . .)*$/)) {
|
||||
echo -ag $me Wins
|
||||
tokenize 32 %ttt~~
|
||||
unset %ttt
|
||||
}
|
||||
elseif ($regex(%ttt,/(?:O . . (?:O|. O .) . . O|. . O . O . O . .)/)) || ($regex(%ttt,/^(?:. . . )*O O O(?: . . .)*$/)) {
|
||||
echo -ag $me Loses
|
||||
unset %ttt
|
||||
}
|
||||
elseif (!$regex(%ttt,/\d/)) {
|
||||
echo -ag Draw
|
||||
unset %ttt
|
||||
}
|
||||
echo -ag <20> $+ $iif($1 isnum,$chr(32),$1) $+ $chr(124) $+ $iif($2 isnum,$chr(32),$2) $+ $chr(124) $+ $iif($3 isnum, ,$3)
|
||||
echo -ag <20> $+ $iif($4 isnum,$chr(32),$4) $+ $chr(124) $+ $iif($5 isnum,$chr(32),$5) $+ $chr(124) $+ $iif($6 isnum, ,$6)
|
||||
echo -ag <20> $+ $iif($7 isnum,$chr(32),$7) $+ $chr(124) $+ $iif($8 isnum,$chr(32),$8) $+ $chr(124) $+ $iif($9 isnum, ,$9)
|
||||
}
|
||||
else {
|
||||
echo -ag Place Taken
|
||||
tokenize 32 %ttt
|
||||
echo -ag <20> $+ $iif($1 isnum,$chr(32),$1) $+ $chr(124) $+ $iif($2 isnum,$chr(32),$2) $+ $chr(124) $+ $iif($3 isnum, ,$3)
|
||||
echo -ag <20> $+ $iif($4 isnum,$chr(32),$4) $+ $chr(124) $+ $iif($5 isnum,$chr(32),$5) $+ $chr(124) $+ $iif($6 isnum, ,$6)
|
||||
echo -ag <20> $+ $iif($7 isnum,$chr(32),$7) $+ $chr(124) $+ $iif($8 isnum,$chr(32),$8) $+ $chr(124) $+ $iif($9 isnum, ,$9)
|
||||
}
|
||||
}
|
||||
379
Task/Tic-tac-toe/Scilab/tic-tac-toe.scilab
Normal file
379
Task/Tic-tac-toe/Scilab/tic-tac-toe.scilab
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
function [] = startGame()
|
||||
//Board size and marks
|
||||
N = 3;
|
||||
marks = ["X" "O"];
|
||||
|
||||
//Creating empty board
|
||||
board = string(zeros(N,N));
|
||||
for i = 1:(N*N)
|
||||
board(i) = "";
|
||||
end
|
||||
|
||||
//Initialising players
|
||||
clc();
|
||||
players= [%F %F];
|
||||
players = playerSetup(marks);
|
||||
|
||||
//Console header
|
||||
header = [strsplit(marks(1)+" is ----")';...
|
||||
strsplit(marks(2)+" is ----")'];
|
||||
for i = 1:2
|
||||
if players(i) then
|
||||
header(i,6:10) = strsplit("P"+string(i)+". ");
|
||||
else
|
||||
header(i,6:10) = strsplit("COMP.");
|
||||
end
|
||||
end
|
||||
|
||||
//Game loop
|
||||
sleep(1000);
|
||||
win_flag = %F;
|
||||
count = 0;
|
||||
while count<N*N
|
||||
//Clear console, and print header and board
|
||||
clc();
|
||||
printf("%s\n %s\n",strcat(header(1,:)),strcat(header(2,:)));
|
||||
dispBoard(board);
|
||||
|
||||
//Find which player should move
|
||||
player_n = modulo(count,2) + 1;
|
||||
|
||||
if players(player_n) == %T then
|
||||
//Human plays
|
||||
pos = [];
|
||||
valid_move = %F;
|
||||
disp(marks(player_n)+"''s turn.");
|
||||
while valid_move ~= %T
|
||||
[pos,valid_move] = readHumanMove(board);
|
||||
if ~valid_move then
|
||||
disp("You should input a valid cell number.");
|
||||
end
|
||||
end
|
||||
|
||||
if valid_move then
|
||||
board = updateBoard(board,pos,marks(player_n));
|
||||
else
|
||||
error("Invalid move.");
|
||||
end
|
||||
else
|
||||
//Computer plays
|
||||
disp("Computer is playing.");
|
||||
board = ComputerMove(board,marks(player_n),marks);
|
||||
sleep(800);
|
||||
end
|
||||
|
||||
//Count number of movements
|
||||
count = count + 1;
|
||||
|
||||
//Check if the game has finished
|
||||
[win_flag,winning_mark] = detectWin(board)
|
||||
if win_flag then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
//Clear screen at the end of game
|
||||
clc();
|
||||
disp("Game finished:");
|
||||
dispBoard(board);
|
||||
|
||||
//Print results
|
||||
if win_flag then
|
||||
disp(winning_mark+" won!");
|
||||
else
|
||||
disp("It''s a tie.");
|
||||
end
|
||||
|
||||
//Play again?
|
||||
play_again = "";
|
||||
while play_again ~= "Y" & play_again ~= "N"
|
||||
play_again = input("Would you like to play again? (Y/N)","s");
|
||||
play_again = strsplit(play_again);
|
||||
play_again = convstr(play_again(1),"u");
|
||||
|
||||
if play_again ~= "Y" & play_again ~= "N" then
|
||||
disp("Invalid answer.");
|
||||
end
|
||||
end
|
||||
|
||||
if play_again == "Y" then
|
||||
startGame();
|
||||
else
|
||||
disp("Quit game.");
|
||||
end
|
||||
endfunction
|
||||
|
||||
function players = playerSetup(marks)
|
||||
//Determines who plays which mark
|
||||
players = [%F %F]; //True for human, Flase for computer
|
||||
|
||||
printf("\n%s always starts.\n",marks(1));
|
||||
for i = 1:2
|
||||
user_input = "";
|
||||
while user_input ~= "Y" & user_input ~= "N"
|
||||
user_input = input("Would you like to play as "+marks(i)+"? (Y/N)","s");
|
||||
user_input = strsplit(user_input);
|
||||
user_input = convstr(user_input(1),"u");
|
||||
|
||||
if user_input ~= "Y" & user_input ~= "N" then
|
||||
disp("Invalid answer.");
|
||||
end
|
||||
end
|
||||
|
||||
//Print choice
|
||||
if user_input == "Y" then
|
||||
players(i) = %T;
|
||||
printf("%s shall be player %d (P%d).\n\n",marks(i),i,i);
|
||||
else
|
||||
printf("%s shall be the computer (COMP).\n\n",marks(i));
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [] = dispBoard(board)
|
||||
//Print ASCII board on console
|
||||
|
||||
//Get board marks
|
||||
marks = [" " " "];
|
||||
mark_inds = find(board ~= "");
|
||||
if mark_inds ~= [] then
|
||||
marks(1) = board(mark_inds(1));
|
||||
mark_inds = find( (board ~= "") & (board ~= marks(1)) );
|
||||
if mark_inds ~= [] then
|
||||
marks(2) = board(mark_inds(1));
|
||||
end
|
||||
end
|
||||
|
||||
//Transpose to display for humans
|
||||
//[compatibility with readHumanMove()]
|
||||
disp_board = board';
|
||||
|
||||
rows = 3*size(board,'r');
|
||||
cols = 4*size(board,'c');
|
||||
ascii_board = string(zeros(rows, cols));
|
||||
|
||||
mark_1=[...
|
||||
strsplit(" |")';...
|
||||
strsplit(" "+marks(1)+" |")';...
|
||||
strsplit("___|")'];
|
||||
|
||||
mark_2=[...
|
||||
strsplit(" |")';...
|
||||
strsplit(" "+marks(2)+" |")';...
|
||||
strsplit("___|")'];
|
||||
|
||||
Blank_mark=[...
|
||||
strsplit(" |")';...
|
||||
strsplit(" |")';...
|
||||
strsplit("___|")'];
|
||||
|
||||
for r = ([1:size(board,'r')] - 1 )
|
||||
for c = ([1:size(board,'c')] - 1)
|
||||
if disp_board(r+1,c+1) == marks(1) then
|
||||
ascii_board((r*3 + 1):((r+1)*3),...
|
||||
(c*4 + 1):((c+1)*4)) = mark_1;
|
||||
elseif disp_board(r+1,c+1) == marks(2) then
|
||||
ascii_board((r*3 + 1):((r+1)*3),...
|
||||
(c*4 + 1):((c+1)*4)) = mark_2;
|
||||
else
|
||||
ascii_board((r*3 + 1):((r+1)*3),...
|
||||
(c*4 + 1):((c+1)*4)) = Blank_mark;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1:cols
|
||||
if modulo(i,4)>0 then
|
||||
ascii_board(rows,i) = " ";
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1:rows
|
||||
ascii_board(i,cols) = " ";
|
||||
end
|
||||
|
||||
printf("\n");
|
||||
for i = 1:size(ascii_board,'r')
|
||||
printf("%s\n",strcat(ascii_board(i,:)))
|
||||
end
|
||||
endfunction
|
||||
|
||||
function moves_board = availableMoves(board)
|
||||
//Find empty cells on the board
|
||||
moves_board = board;
|
||||
|
||||
for i = 1:(size(board,'r')*size(board,'c'))
|
||||
if board(i) == "" then
|
||||
moves_board(i) = string(i);
|
||||
else
|
||||
moves_board(i) = "_";
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function varargout = readHumanMove(board)
|
||||
//Read human input
|
||||
printf("\nAvailable cells:");
|
||||
moves_board = availableMoves(board);
|
||||
disp(moves_board');
|
||||
|
||||
x = input("\nEnter a move (0 to quit game): ");
|
||||
|
||||
valid = %F;
|
||||
pos = 0;
|
||||
total = size(moves_board,'r') * size(moves_board,'c');
|
||||
|
||||
//Check if it is a valid move
|
||||
if x == 0 then
|
||||
disp("Quit game.")
|
||||
abort
|
||||
elseif (x>=1 & x<=total) then
|
||||
if (moves_board(x) == string(x)) then
|
||||
valid = %T;
|
||||
pos = x;
|
||||
end
|
||||
end
|
||||
|
||||
varargout = list(pos,valid);
|
||||
endfunction
|
||||
|
||||
function varargout = updateBoard(board,pos,player)
|
||||
//Add move to the board
|
||||
if board(pos) ~= "" then
|
||||
error('Error: Invalid move.');
|
||||
end
|
||||
|
||||
board(pos) = player
|
||||
|
||||
varargout = list(board);
|
||||
endfunction
|
||||
|
||||
function varargout = detectWin(board)
|
||||
//Detect if there is a winner or not
|
||||
win_flag = %F;
|
||||
winner = "";
|
||||
|
||||
//Get board marks
|
||||
marks = ["" ""];
|
||||
mark_inds = find(board ~= "");
|
||||
marks(1) = board(mark_inds(1))
|
||||
mark_inds = find( (board ~= "") & (board ~= marks(1)) );
|
||||
marks(2) = board(mark_inds(1));
|
||||
|
||||
//If there is a minimum number of moves, check if there is a winner
|
||||
n_moves = find(~(board == ""));
|
||||
n_moves = length(n_moves)
|
||||
|
||||
if n_moves >= size(board,'r') then
|
||||
board_X = (board == marks(1));
|
||||
board_O = (board == marks(2));
|
||||
|
||||
for i = 1:size(board,'r')
|
||||
//Check rows
|
||||
if find(~board_X(i,:)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(1);
|
||||
break
|
||||
end
|
||||
if find(~board_O(i,:)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(2);
|
||||
break
|
||||
end
|
||||
|
||||
//Check columns
|
||||
if find(~board_X(:,i)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(1);
|
||||
break
|
||||
end
|
||||
if find(~board_O(:,i)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(2);
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
//Check diagonal
|
||||
if ~win_flag then
|
||||
if find(~diag(board_X)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(1);
|
||||
elseif find(~diag(board_O)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(2);
|
||||
end
|
||||
end
|
||||
|
||||
//Check anti-diagonal
|
||||
if ~win_flag then
|
||||
board_X = board_X(:,$:-1:1);
|
||||
board_O = board_O(:,$:-1:1);
|
||||
|
||||
if find(~diag(board_X)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(1);
|
||||
elseif find(~diag(board_O)) == [] then
|
||||
win_flag = %T;
|
||||
winner = marks(2);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
varargout = list(win_flag,winner)
|
||||
endfunction
|
||||
|
||||
function threat_pos = findThreat(board,player)
|
||||
//Returns a list of moves that can finish the game
|
||||
|
||||
//Available moves
|
||||
move_inds = find(~( availableMoves(board) == "_" ));
|
||||
|
||||
//If there is a minimum number of moves, check if there is a threat
|
||||
threat_pos = [];
|
||||
if (size(board,'r')*size(board,'c')) - length(move_inds) >...
|
||||
(size(board,'r') - 1) then
|
||||
for i = 1:length(move_inds)
|
||||
temp_board = updateBoard(board,move_inds(i),player);
|
||||
[win_flag,winner] = detectWin(temp_board);
|
||||
if win_flag & winner == player then
|
||||
threat_pos = [threat_pos move_inds(i)];
|
||||
end
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function varargout = ComputerMove(board,mark,all_marks)
|
||||
//Atomatically add a move to the board with no human input
|
||||
|
||||
//Find winning moves moves
|
||||
move_inds = findThreat(board,mark);
|
||||
|
||||
//If there are no winning moves, find opponent's winning moves
|
||||
//to block opponent's victory
|
||||
if move_inds == [] then
|
||||
if mark == all_marks(1) then
|
||||
opponent = all_marks(2);
|
||||
elseif mark == all_marks(2) then
|
||||
opponent = all_marks(1);
|
||||
end
|
||||
|
||||
move_inds = findThreat(board,opponent);
|
||||
end
|
||||
|
||||
//If there are no winning moves or threats, find all possible moves
|
||||
if move_inds == [] then
|
||||
move_inds = find(~( availableMoves(board) == "_" ));
|
||||
end
|
||||
|
||||
//Choose a random move among the selected possible moves
|
||||
pos = grand(1,"prm",move_inds);
|
||||
pos = pos(1);
|
||||
|
||||
//Update board by adding a new mark
|
||||
board(pos) = mark;
|
||||
|
||||
varargout = list(board);
|
||||
endfunction
|
||||
|
||||
startGame()
|
||||
206
Task/Tic-tac-toe/Swift/tic-tac-toe.swift
Normal file
206
Task/Tic-tac-toe/Swift/tic-tac-toe.swift
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
import Darwin
|
||||
|
||||
enum Token : CustomStringConvertible {
|
||||
case cross, circle
|
||||
|
||||
func matches(tokens: [Token?]) -> Bool {
|
||||
for token in tokens {
|
||||
guard let t = token, t == self else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func emptyCell(in tokens: [Token?]) -> Int? {
|
||||
if tokens[0] == nil
|
||||
&& tokens[1] == self
|
||||
&& tokens[2] == self {
|
||||
return 0
|
||||
} else
|
||||
if tokens[0] == self
|
||||
&& tokens[1] == nil
|
||||
&& tokens[2] == self {
|
||||
return 1
|
||||
} else
|
||||
if tokens[0] == self
|
||||
&& tokens[1] == self
|
||||
&& tokens[2] == nil {
|
||||
return 2
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .cross: return "x"
|
||||
case .circle: return "o"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Board {
|
||||
var cells: [Token?] = [nil, nil, nil, nil, nil, nil, nil, nil, nil]
|
||||
|
||||
func cells(atCol col: Int) -> [Token?] {
|
||||
return [cells[col], cells[col + 3], cells[col + 6]]
|
||||
}
|
||||
|
||||
func cells(atRow row: Int) -> [Token?] {
|
||||
return [cells[row * 3], cells[row * 3 + 1], cells[row * 3 + 2]]
|
||||
}
|
||||
|
||||
func cellsTopLeft() -> [Token?] {
|
||||
return [cells[0], cells[4], cells[8]]
|
||||
}
|
||||
|
||||
func cellsBottomLeft() -> [Token?] {
|
||||
return [cells[6], cells[4], cells[2]]
|
||||
}
|
||||
|
||||
func winner() -> Token? {
|
||||
let r0 = cells(atRow: 0)
|
||||
let r1 = cells(atRow: 1)
|
||||
let r2 = cells(atRow: 2)
|
||||
let c0 = cells(atCol: 0)
|
||||
let c1 = cells(atCol: 1)
|
||||
let c2 = cells(atCol: 2)
|
||||
let tl = cellsTopLeft()
|
||||
let bl = cellsBottomLeft()
|
||||
|
||||
if Token.cross.matches(tokens: r0)
|
||||
|| Token.cross.matches(tokens: r1)
|
||||
|| Token.cross.matches(tokens: r2)
|
||||
|| Token.cross.matches(tokens: c0)
|
||||
|| Token.cross.matches(tokens: c1)
|
||||
|| Token.cross.matches(tokens: c2)
|
||||
|| Token.cross.matches(tokens: tl)
|
||||
|| Token.cross.matches(tokens: bl) {
|
||||
return .cross
|
||||
} else
|
||||
if Token.circle.matches(tokens: r0)
|
||||
|| Token.circle.matches(tokens: r1)
|
||||
|| Token.circle.matches(tokens: r2)
|
||||
|| Token.circle.matches(tokens: c0)
|
||||
|| Token.circle.matches(tokens: c1)
|
||||
|| Token.circle.matches(tokens: c2)
|
||||
|| Token.circle.matches(tokens: tl)
|
||||
|| Token.circle.matches(tokens: bl) {
|
||||
return .circle
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func atCapacity() -> Bool {
|
||||
return cells.filter { $0 == nil }.count == 0
|
||||
}
|
||||
|
||||
mutating func play(token: Token, at location: Int) {
|
||||
cells[location] = token
|
||||
}
|
||||
|
||||
func findBestLocation(for player: Token) -> Int? {
|
||||
let r0 = cells(atRow: 0)
|
||||
let r1 = cells(atRow: 1)
|
||||
let r2 = cells(atRow: 2)
|
||||
let c0 = cells(atCol: 0)
|
||||
let c1 = cells(atCol: 1)
|
||||
let c2 = cells(atCol: 2)
|
||||
let tl = cellsTopLeft()
|
||||
let bl = cellsBottomLeft()
|
||||
|
||||
if let cell = player.emptyCell(in: r0) {
|
||||
return cell
|
||||
} else if let cell = player.emptyCell(in: r1) {
|
||||
return cell + 3
|
||||
} else if let cell = player.emptyCell(in: r2) {
|
||||
return cell + 6
|
||||
} else if let cell = player.emptyCell(in: c0) {
|
||||
return cell * 3
|
||||
} else if let cell = player.emptyCell(in: c1) {
|
||||
return cell * 3 + 1
|
||||
} else if let cell = player.emptyCell(in: c2) {
|
||||
return cell * 3 + 2
|
||||
} else if let cell = player.emptyCell(in: tl) {
|
||||
return cell == 0 ? 0 : (cell == 1 ? 4 : 8)
|
||||
} else if let cell = player.emptyCell(in: bl) {
|
||||
return cell == 0 ? 6 : (cell == 1 ? 4 : 2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func findMove() -> Int {
|
||||
let empties = cells.enumerated().filter { $0.1 == nil }
|
||||
let r = Int(arc4random()) % empties.count
|
||||
return empties[r].0
|
||||
}
|
||||
}
|
||||
|
||||
extension Board : CustomStringConvertible {
|
||||
var description: String {
|
||||
var result = "\n---------------\n"
|
||||
for (idx, cell) in cells.enumerated() {
|
||||
if let cell = cell {
|
||||
result += "| \(cell) |"
|
||||
} else {
|
||||
result += "| \(idx) |"
|
||||
}
|
||||
|
||||
if (idx + 1) % 3 == 0 {
|
||||
result += "\n---------------\n"
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
while true {
|
||||
var board = Board()
|
||||
print("Who do you want to play as ('o' or 'x'): ", separator: "", terminator: "")
|
||||
let answer = readLine()?.characters.first ?? "x"
|
||||
|
||||
var player: Token = answer == "x" ? .cross : .circle
|
||||
var pc: Token = player == .cross ? .circle : .cross
|
||||
|
||||
print(board)
|
||||
|
||||
while true {
|
||||
print("Choose cell to play on: ", separator: "", terminator: "")
|
||||
var pos = Int(readLine() ?? "0") ?? 0
|
||||
while !board.atCapacity() && board.cells[pos] != nil {
|
||||
print("Invalid move. Choose cell to play on: ", separator: "", terminator: "")
|
||||
pos = Int(readLine() ?? "0") ?? 0
|
||||
}
|
||||
|
||||
if board.atCapacity() {
|
||||
print("Draw")
|
||||
break
|
||||
}
|
||||
|
||||
board.play(token: player, at: pos)
|
||||
print(board)
|
||||
|
||||
if let winner = board.winner() {
|
||||
print("winner is \(winner)")
|
||||
break
|
||||
} else if board.atCapacity() {
|
||||
print("Draw")
|
||||
break
|
||||
}
|
||||
|
||||
if let win = board.findBestLocation(for: pc) {
|
||||
board.play(token: pc, at: win)
|
||||
} else if let def = board.findBestLocation(for: player) {
|
||||
board.play(token: pc, at: def)
|
||||
} else {
|
||||
board.play(token: pc, at: board.findMove())
|
||||
}
|
||||
|
||||
print(board)
|
||||
|
||||
if let winner = board.winner() {
|
||||
print("winner is \(winner)")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue