WN26XTZ7IZN4WNAVXZ4NKD4CXIU7IC6V7BFNVICNMQUVHBZXBNCAC
if (move == null) {
return this;
}
return GameWithOneMove(winner: currentPlayer, currentPlayer: Player.SECOND);
var newScores = {
Player.FIRST: 1,
Player.SECOND: 0,
};
return GameWithOneMove(
winner: currentPlayer, scores: newScores, currentPlayer: Player.SECOND);
class TicTacToeGame implements GameState<int, TicTacToePlayer> {
List<TicTacToePlayer> board = [];
TicTacToePlayer currentPlayer;
TicTacToePlayer winner;
TicTacToeGame({this.board, this.currentPlayer, this.winner});
class TicTacToeGame implements GameState<int?, TicTacToePlayer> {
List<TicTacToePlayer?>? board = [];
TicTacToePlayer? currentPlayer;
TicTacToePlayer? winner;
Map<TicTacToePlayer, int> scores = {
TicTacToePlayer.O: 0,
TicTacToePlayer.X: 0,
};
TicTacToeGame(
{this.board, required this.scores, this.currentPlayer, this.winner});
board: List.from([null, null, null, null, null, null, null, null, null]),
currentPlayer: TicTacToePlayer.O);
board:
List.from([null, null, null, null, null, null, null, null, null]),
currentPlayer: TicTacToePlayer.O,
scores: {
TicTacToePlayer.O: 0,
TicTacToePlayer.X: 0,
});
newBoard.asMap().forEach((index, player) => {
if (player != null)
{scoreByPlayer[player] += pow(2.0, index.toDouble()).toInt()}
});
newBoard.asMap().forEach((index, player) {
if (player != null) {
int addScore = pow(2.0, index.toDouble()).toInt();
scoreByPlayer.update(player, (score) => score + addScore,
ifAbsent: () => addScore);
}
});
board: newBoard, winner: newWinner, currentPlayer: newCurrentPlayer);
board: newBoard,
winner: newWinner,
scores: newScores,
currentPlayer: newCurrentPlayer);
}
}
enum ScoringMove { SCORE_5, SCORE_10, SCORE_100 }
class GameWithScore implements GameState<ScoringMove, Player?> {
Player? currentPlayer = Player.FIRST;
Map<Player?, int> scores = {Player.FIRST: 0, Player.SECOND: 0};
Player? winner;
int round = 0;
GameWithScore(
{this.winner,
required this.scores,
this.round = 0,
this.currentPlayer = Player.FIRST});
@override
GameWithScore cloneAndApplyMove(ScoringMove move) {
var newPlayer, newScores, newWinner;
newScores = new Map<Player, int>.from(scores);
// process move
switch (move) {
case ScoringMove.SCORE_5:
newScores.update(currentPlayer, (int score) => score + 5,
ifAbsent: () => 5);
break;
case ScoringMove.SCORE_10:
newScores.update(currentPlayer, (int score) => score + 10,
ifAbsent: () => 10);
break;
case ScoringMove.SCORE_100:
newScores.update(currentPlayer, (int score) => score + 100,
ifAbsent: () => 100);
break;
}
// change current player for the next play
if (currentPlayer == Player.FIRST) {
newPlayer = Player.SECOND;
} else {
newPlayer = Player.FIRST;
}
// check win conditions
if (newScores[Player.FIRST] > 100 &&
newScores[Player.FIRST] > newScores[Player.SECOND]) {
newWinner = Player.FIRST;
} else if (newScores[Player.SECOND] > 100) {
newWinner = Player.SECOND;
}
return GameWithScore(
winner: newWinner,
round: round + 1,
scores: newScores,
currentPlayer: newPlayer);
}
@override
List<ScoringMove> getMoves() {
if (winner != null) {
return [];
}
return [ScoringMove.SCORE_5, ScoringMove.SCORE_10, ScoringMove.SCORE_100];
var oneMoveFromWinning =
TicTacToeGame(board: [o, o, e, x, e, x, e, x, e], currentPlayer: o);
var result = MCTS(gameState: oneMoveFromWinning)
.getSimulationResult(iterations: 100);
expect(result.root.children.length, equals(4));
var oneMoveFromWinning = TicTacToeGame(
board: [o, o, e, x, e, x, e, x, e], currentPlayer: o, scores: {});
MCTSResult<int?, TicTacToePlayer> result =
MCTS(gameState: oneMoveFromWinning)
.getSimulationResult(iterations: 100);
expect(result.root!.children.length, equals(4));
var oneMoveFromWinning =
TicTacToeGame(board: [o, e, e, o, x, x, e, x, e], currentPlayer: o);
var result = MCTS(gameState: oneMoveFromWinning)
.getSimulationResult(iterations: 100);
expect(result.root.children.length, equals(4));
var oneMoveFromWinning = TicTacToeGame(
board: [o, e, e, o, x, x, e, x, e], currentPlayer: o, scores: {});
MCTSResult<int?, TicTacToePlayer> result =
MCTS(gameState: oneMoveFromWinning)
.getSimulationResult(iterations: 100);
expect(result.root!.children.length, equals(4));
test('test', () {
int gamesPlayed = 0;
for (var _ = 0; _ < 1000; _++) {
TicTacToeGame gameState = TicTacToeGame.newGame();
test('plays out a game from start to finish', () {
for (var _ = 0; _ < 100; _++) {
TicTacToeGame gameState = TicTacToeGame.newGame() as TicTacToeGame;
print(gamesPlayed);
});
test(
'game with a score selects high scoring moves more frequently than low scoring moves',
() {
var gameState = GameWithScore(scores: {Player.FIRST: 0, Player.SECOND: 0});
MCTSResult<ScoringMove, Player?> result =
MCTS(gameState: gameState).getSimulationResult(iterations: 100);
expect(result.root!.children.length, equals(3));
expect(result.move, equals(ScoringMove.SCORE_100));
expect(result.root!.children[ScoringMove.SCORE_100]?.visits ?? 0,
greaterThan(50));
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.39.10"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "0.4.2"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.7"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.2"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
version: "1.1.0"
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.12"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
dart_style:
dependency: transitive
description:
name: dart_style
version: "0.3.0+1"
dataclass_generator:
dependency: "direct dev"
description:
name: dataclass_generator
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0+2"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
version: "1.2.0"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+3"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.2"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "0.11.4"
version: "0.9.6+3"
node_interop:
dependency: transitive
description:
name: node_interop
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
node_io:
dependency: transitive
description:
name: node_io
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
version: "1.7.0"
version: "1.9.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.5"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.3"
version: "1.8.0"
version: "0.9.7+15"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
version: "2.1.0"
class TicTacToeGame implements GameState<int, TicTacToePlayer> {
List<TicTacToePlayer> board;
TicTacToePlayer currentPlayer;
TicTacToePlayer winner;
TicTacToeGame({this.board, this.currentPlayer, this.winner});
class TicTacToeGame implements GameState<int?, TicTacToePlayer> {
List<TicTacToePlayer?> board =
List.from([null, null, null, null, null, null, null, null, null]);
TicTacToePlayer? currentPlayer;
TicTacToePlayer? winner;
Map<TicTacToePlayer, int> scores = {
TicTacToePlayer.O: 0,
TicTacToePlayer.X: 0
};
TicTacToeGame({required this.board, this.currentPlayer, this.winner});
GameState<MoveType, PlayerType> determine(
GameState<MoveType, PlayerType> initialState);
PlayerType winner;
PlayerType currentPlayer;
GameState<MoveType, PlayerType>? determine(
GameState<MoveType, PlayerType>? initialState);
PlayerType? winner;
PlayerType? currentPlayer;
Map<PlayerType, int> scores = {};
return (((winsByPlayer[player] ?? 0) + (draws * 0.5)) / visits) +
(c * sqrt(log(parent.visits.toDouble() / visits)));
double normalizedScore = (maxScoreByPlayer[player] ?? 0) / maxScore;
var ucb = (normalizedScore *
(winsByPlayer[player] ?? 0 + (draws * 0.5)) /
visits) +
(c * sqrt(log(parent!.visits.toDouble() / visits)));
return ucb;
if (!currentNode.winsByPlayer.containsKey(winner)) {
currentNode.winsByPlayer[winner] = 0;
}
currentNode.winsByPlayer[winner] += 1;
gameState!.scores.forEach((player, score) {
currentNode!.maxScoreByPlayer.update(
player, (value) => score > value ? score : value,
ifAbsent: () => score);
currentNode.minScoreByPlayer.update(
player, (value) => score < value ? score : value,
ifAbsent: () => score);
});
currentNode.winsByPlayer
.update(winner, (value) => value + 1, ifAbsent: () => 0);
final Node<MoveType, PlayerType> root;
final MoveType move;
final List<Node<MoveType, PlayerType>> leafNodes;
final int maxDepth;
final int plays;
final Node<MoveType, PlayerType>? root;
final MoveType? move;
final List<Node<MoveType, PlayerType>>? leafNodes;
final int? maxDepth;
final int? plays;