-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Not sure why everything got changed...
- Loading branch information
Showing
28 changed files
with
1,570 additions
and
1,518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto | ||
|
||
# Custom for Visual Studio | ||
*.cs diff=csharp | ||
*.sln merge=union | ||
*.csproj merge=union | ||
*.vbproj merge=union | ||
*.fsproj merge=union | ||
*.dbproj merge=union | ||
|
||
# Standard to msysgit | ||
*.doc diff=astextplain | ||
*.DOC diff=astextplain | ||
*.docx diff=astextplain | ||
*.DOCX diff=astextplain | ||
*.dot diff=astextplain | ||
*.DOT diff=astextplain | ||
*.pdf diff=astextplain | ||
*.PDF diff=astextplain | ||
*.rtf diff=astextplain | ||
*.RTF diff=astextplain | ||
# Auto detect text files and perform LF normalization | ||
* text=auto | ||
|
||
# Custom for Visual Studio | ||
*.cs diff=csharp | ||
*.sln merge=union | ||
*.csproj merge=union | ||
*.vbproj merge=union | ||
*.fsproj merge=union | ||
*.dbproj merge=union | ||
|
||
# Standard to msysgit | ||
*.doc diff=astextplain | ||
*.DOC diff=astextplain | ||
*.docx diff=astextplain | ||
*.DOCX diff=astextplain | ||
*.dot diff=astextplain | ||
*.DOT diff=astextplain | ||
*.pdf diff=astextplain | ||
*.PDF diff=astextplain | ||
*.rtf diff=astextplain | ||
*.RTF diff=astextplain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Monte-Carlo-Games | ||
Strategy-free robot board games. | ||
|
||
Learn more here http://blogs.mathworks.com/community/2015/01/09/robot-game-playing-in-matlab/ | ||
# Monte-Carlo-Games | ||
Strategy-free robot board games. | ||
|
||
Learn more here http://blogs.mathworks.com/community/2015/01/09/robot-game-playing-in-matlab/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,126 @@ | ||
function botMoves(game,nGames) | ||
% game: a class | ||
% nGames: number of random simulated game to run for each potential move. | ||
|
||
% Find all the legal moves | ||
moves = game.possibleMoves; | ||
side = game.whoseMove; | ||
resultCounts = []; | ||
|
||
if isempty(moves) | ||
% No moves are possible. | ||
fprintf('No moves remain. Game is over.\n') | ||
return | ||
|
||
elseif length(moves)==1 | ||
% One move is possible. Make it. | ||
move = moves; | ||
|
||
else | ||
% More than one move is possible. Which is the best one? | ||
resultCounts = ratePossibleMoves(game,moves,side,nGames); | ||
|
||
% Maximize likelihood of not losing (i.e. maximize victory + draw) | ||
resultCountsNoLose = resultCounts(:,side) + resultCounts(:,3); | ||
|
||
% Or maximize likelihood of victory only (ignore draws) | ||
resultCountsWinOnly = resultCounts(:,side); | ||
|
||
[~,ix] = max(resultCountsNoLose); | ||
|
||
move = moves(ix); | ||
|
||
showRatingsFlag = false; | ||
if showRatingsFlag | ||
showRatings(side, resultCounts, moves, ix) | ||
end | ||
|
||
end | ||
|
||
game.makeMove(move,side); | ||
game.showBoard | ||
|
||
end | ||
|
||
function winnerCounts = ratePossibleMoves(game,possibleMoveList,mySide,nGames) | ||
|
||
nPossibleMoves = length(possibleMoveList); | ||
winnerCounts = zeros(nPossibleMoves,3); | ||
|
||
otherSide = toggleSide(mySide); | ||
|
||
for i = 1:nPossibleMoves | ||
newGame = game.copy; | ||
newGame.makeMove(possibleMoveList(i),mySide); | ||
whoWins = playManyGames(newGame,nGames); | ||
winnerCounts(i,:) = whoWins; | ||
end | ||
|
||
end | ||
|
||
function whoWins = playManyGames(game,nGames) | ||
% From the current board, play many random games and report the results. | ||
% nGames: how many games to play | ||
% whoWins is a 1x3 vector: [wins for side 1, wins for side 2, draw] | ||
|
||
whoWins = [0 0 0]; | ||
|
||
% Is the game is already over? | ||
winner = game.isGameOver; | ||
if winner | ||
whoWins(winner) = nGames; | ||
return | ||
end | ||
|
||
for i = 1:nGames | ||
randGame = game.copy; | ||
gameOver = false; | ||
while ~gameOver | ||
side = randGame.whoseMove; | ||
move = randomMove(randGame); | ||
randGame.makeMove(move,side); | ||
winner = randGame.isGameOver; | ||
% winner will be 0 (undetermined), 1, 2, or 3 (tie) | ||
if winner | ||
whoWins(winner) = whoWins(winner) + 1; | ||
gameOver = true; | ||
end | ||
end | ||
end | ||
|
||
end | ||
|
||
function move = randomMove(game) | ||
% Pick exactly one of the legal moves | ||
moves = game.possibleMoves; | ||
move = moves(ceil(rand*length(moves))); | ||
end | ||
|
||
function sideOut = toggleSide(sideIn) | ||
sideOut = 3 - sideIn; | ||
end | ||
|
||
function showRatings(side, resultCounts, moves, ix) | ||
|
||
fprintf('\nSIDE %d TO MOVE\n',side); | ||
if side==1 | ||
fprintf(' Move Wins Loses Ties\n') | ||
else | ||
fprintf(' Move Loses Wins Ties\n') | ||
end | ||
fprintf(' ------ ------ ------ ------\n') | ||
for i = 1:length(moves) | ||
if i==ix | ||
str1 = ' >'; | ||
str2 = '< '; | ||
else | ||
str1 = ' '; | ||
str2 = ' '; | ||
end | ||
fprintf('%s%5d. %6d %6d %6d %s\n', ... | ||
str1, moves(i), ... | ||
resultCounts(i,1), resultCounts(i,2), resultCounts(i,3), ... | ||
str2) | ||
end | ||
fprintf(' ------ ------ ------ ------\n') | ||
end | ||
function botMoves(game,nGames) | ||
% game: a class | ||
% nGames: number of random simulated game to run for each potential move. | ||
|
||
% Find all the legal moves | ||
moves = game.possibleMoves; | ||
side = game.whoseMove; | ||
resultCounts = []; | ||
|
||
if isempty(moves) | ||
% No moves are possible. | ||
fprintf('No moves remain. Game is over.\n') | ||
return | ||
|
||
elseif length(moves)==1 | ||
% One move is possible. Make it. | ||
move = moves; | ||
|
||
else | ||
% More than one move is possible. Which is the best one? | ||
resultCounts = ratePossibleMoves(game,moves,side,nGames); | ||
|
||
% Maximize likelihood of not losing (i.e. maximize victory + draw) | ||
resultCountsNoLose = resultCounts(:,side) + resultCounts(:,3); | ||
|
||
% Or maximize likelihood of victory only (ignore draws) | ||
resultCountsWinOnly = resultCounts(:,side); | ||
|
||
[~,ix] = max(resultCountsNoLose); | ||
|
||
move = moves(ix); | ||
|
||
showRatingsFlag = false; | ||
if showRatingsFlag | ||
showRatings(side, resultCounts, moves, ix) | ||
end | ||
|
||
end | ||
|
||
game.makeMove(move,side); | ||
game.showBoard | ||
|
||
end | ||
|
||
function winnerCounts = ratePossibleMoves(game,possibleMoveList,mySide,nGames) | ||
|
||
nPossibleMoves = length(possibleMoveList); | ||
winnerCounts = zeros(nPossibleMoves,3); | ||
|
||
otherSide = toggleSide(mySide); | ||
|
||
for i = 1:nPossibleMoves | ||
newGame = game.copy; | ||
newGame.makeMove(possibleMoveList(i),mySide); | ||
whoWins = playManyGames(newGame,nGames); | ||
winnerCounts(i,:) = whoWins; | ||
end | ||
|
||
end | ||
|
||
function whoWins = playManyGames(game,nGames) | ||
% From the current board, play many random games and report the results. | ||
% nGames: how many games to play | ||
% whoWins is a 1x3 vector: [wins for side 1, wins for side 2, draw] | ||
|
||
whoWins = [0 0 0]; | ||
|
||
% Is the game is already over? | ||
winner = game.isGameOver; | ||
if winner | ||
whoWins(winner) = nGames; | ||
return | ||
end | ||
|
||
for i = 1:nGames | ||
randGame = game.copy; | ||
gameOver = false; | ||
while ~gameOver | ||
side = randGame.whoseMove; | ||
move = randomMove(randGame); | ||
randGame.makeMove(move,side); | ||
winner = randGame.isGameOver; | ||
% winner will be 0 (undetermined), 1, 2, or 3 (tie) | ||
if winner | ||
whoWins(winner) = whoWins(winner) + 1; | ||
gameOver = true; | ||
end | ||
end | ||
end | ||
|
||
end | ||
|
||
function move = randomMove(game) | ||
% Pick exactly one of the legal moves | ||
moves = game.possibleMoves; | ||
move = moves(ceil(rand*length(moves))); | ||
end | ||
|
||
function sideOut = toggleSide(sideIn) | ||
sideOut = 3 - sideIn; | ||
end | ||
|
||
function showRatings(side, resultCounts, moves, ix) | ||
|
||
fprintf('\nSIDE %d TO MOVE\n',side); | ||
if side==1 | ||
fprintf(' Move Wins Loses Ties\n') | ||
else | ||
fprintf(' Move Loses Wins Ties\n') | ||
end | ||
fprintf(' ------ ------ ------ ------\n') | ||
for i = 1:length(moves) | ||
if i==ix | ||
str1 = ' >'; | ||
str2 = '< '; | ||
else | ||
str1 = ' '; | ||
str2 = ' '; | ||
end | ||
fprintf('%s%5d. %6d %6d %6d %s\n', ... | ||
str1, moves(i), ... | ||
resultCounts(i,1), resultCounts(i,2), resultCounts(i,3), ... | ||
str2) | ||
end | ||
fprintf(' ------ ------ ------ ------\n') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,27 @@ | ||
%% Connect Four Robot vs. Robot | ||
% Initialize | ||
|
||
gameType = 4; | ||
switch gameType | ||
case 1 | ||
game = ConnectFour; | ||
case 2 | ||
game = ConnectEl; | ||
case 3 | ||
game = ConnectTee; | ||
case 4 | ||
game = FourCorners; | ||
end | ||
|
||
game.showResult | ||
|
||
% Two robots play until the game is over | ||
nGamesSide1 = 1000; | ||
nGamesSide2 = 1000; | ||
while ~game.isGameOver | ||
botMoves(game,nGamesSide1); | ||
|
||
if ~game.isGameOver | ||
botMoves(game,nGamesSide2); | ||
end | ||
end | ||
%% Connect Four Robot vs. Robot | ||
% Initialize | ||
|
||
gameType = 4; | ||
switch gameType | ||
case 1 | ||
game = ConnectFour; | ||
case 2 | ||
game = ConnectEl; | ||
case 3 | ||
game = ConnectTee; | ||
case 4 | ||
game = FourCorners; | ||
end | ||
|
||
game.showResult | ||
|
||
% Two robots play until the game is over | ||
nGamesSide1 = 1000; | ||
nGamesSide2 = 1000; | ||
while ~game.isGameOver | ||
botMoves(game,nGamesSide1); | ||
|
||
if ~game.isGameOver | ||
botMoves(game,nGamesSide2); | ||
end | ||
end |
Oops, something went wrong.