added Brain for second Player

This commit is contained in:
Shuozhe 2021-07-25 01:21:22 +02:00
parent 0edb73d8a3
commit 1a110b213a
8 changed files with 109 additions and 43 deletions

View File

@ -35,10 +35,10 @@ namespace ProjectGrid.Controllers
[HttpGet]
[Route("api/ttt/Restart")]
public void RestartGame()
public void RestartGame(TicTacToc.Mode mode = TicTacToc.Mode.CROSS_PLAYER)
{
_logger.LogTrace("RestartGame called.");
_manager.Restart();
_manager.Restart(mode);
}
[HttpPost]

View File

@ -16,7 +16,7 @@ namespace ProjectGrid.Data
}
public Models.TicTacTocBrain GetBoard()
public TicTacTocBoard GetBoard()
{
throw new System.NotImplementedException();
}

View File

@ -4,7 +4,7 @@ namespace ProjectGrid.Data
{
public interface ITicTacToctRepository
{
TicTacTocBrain GetBoard();
TicTacTocBoard GetBoard();
bool AddPiece(TicTacTocRequest user);
}

View File

@ -2,6 +2,7 @@ using ProjectGrid.Models;
using ProjectGrid.TicTacToc;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ProjectGrid.AI
@ -13,10 +14,10 @@ namespace ProjectGrid.AI
private List<int> _prio;
public TicTacTocBrain(TicTacTocBoard board, Player player)
public TicTacTocBrain(TicTacTocBoard board, int player)
{
_board = board;
_player = (int)player;
_player = player;
var rand = new Random();
_prio = (new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }).OrderBy(i => rand.Next()).ToList();
@ -24,45 +25,68 @@ namespace ProjectGrid.AI
public int Turn()
{
if (_board.Field[5] == (int)Player.EMPTY)
if (_board.Field[4] == (int)Player.EMPTY)
{
//_board.SetFieldValue(_player, 5);
return 5;
return 4;
}
int blocking = -1;
for (int x = 0; x < TicTacTocBoard._winning.GetLength(0); x++)
{
var _1 = TicTacTocBoard._winning[x, 0];
var _2 = TicTacTocBoard._winning[x, 1];
var _3 = TicTacTocBoard._winning[x, 2];
var _1 = _board.Field[TicTacTocBoard._winning[x, 0]];
var _2 = _board.Field[TicTacTocBoard._winning[x, 1]];
var _3 = _board.Field[TicTacTocBoard._winning[x, 2]];
int result = Match2(_1, _2, _3);
if (result > 0)
{
//_board.SetFieldValue(_player, );
return TicTacTocBoard._winning[x, result];
}
// any field set?
if (_1 + _2 + _3 == 0)
continue;
var result = MatchWinning(_1, _2, _3);
if (result.Item1 >= 0)
return TicTacTocBoard._winning[x, result.Item1];
if (result.Item2 >= 0)
blocking = TicTacTocBoard._winning[x, result.Item2];
}
if (blocking >= 0)
return blocking;
foreach (var i in _prio)
if (_board.Field[i] == 0)
return i;
Debug.Fail("Brain found no valid move!");
return -1;
}
private int Match2(int _1, int _2, int _3)
private (int win, int block) MatchWinning(int _1, int _2, int _3)
{
if (_1 == _player && _2 == _player && _3 == 0)
return 3;
(int win, int block) result = (-1, -1);
if (_1 == _2 && _1 != 0 && _3 == 0)
{
if (_1 == _player)
result.win = 2;
else
result.block = 2;
}
else if (_1 == _3 && _1 != 0 && _2 == 0)
{
if (_1 == _player)
result.win = 1;
else
result.block = 1;
}
else if (_2 == _3 && _2 != 0 && _1 == 0)
{
if (_1 == _player)
result.win = 0;
else
result.block = 0;
}
if (_1 == _player && _2 == 0 && _3 == _player)
return 2;
if (_1 == 0 && _2 == _player && _3 == _player)
return 1;
return 0;
return result;
}
}
}

View File

@ -15,6 +15,8 @@ namespace ProjectGrid.Models
private int _lastSetValue;
public int LastSetValue => _lastSetValue;
public bool Full => !!!_field.Contains(0);
private int PosToIdx(int x, int y)
{
Debug.Assert(x >= 0 && x <= 3

View File

@ -1,3 +1,4 @@
using ProjectGrid.AI;
using ProjectGrid.Models;
using ProjectGrid.TicTacToc;
using System;
@ -22,6 +23,9 @@ namespace ProjectGrid
}
private State _state;
private Mode _mode;
private TicTacTocBrain _brain;
//private ITicTacToctRepository _repo;
@ -36,7 +40,7 @@ namespace ProjectGrid
{
//_repo = repo;
_currentPlayer = 1;
Restart(Mode.TWO_PLAYER);
Restart(Mode.CROSS_PLAYER);
}
public TicTacTocResponse NextMove(TicTacTocRequest move)
@ -45,8 +49,8 @@ namespace ProjectGrid
if (_state != State.GAME_OVER)
{
_board.SetFieldValue(_currentPlayer, move.Field);
if (_board.SetFieldValue(_currentPlayer, move.Field))
{
response.Winning = _board.ValueWon(_currentPlayer);
if (_currentPlayer > 0 && response.Winning != null)
{
@ -54,10 +58,41 @@ namespace ProjectGrid
_state = State.GAME_OVER;
_playerScore[_currentPlayer]++;
}
else if (null != _brain)
{
if (_board.Full)
{
_playerScore[0]++;
_state = State.GAME_OVER;
response.PlayerWon = 0;
return response;
}
int ai = 3 - _currentPlayer;
var turn = _brain.Turn();
Console.WriteLine($"Brain made move {turn} for player {ai}");
_board.SetFieldValue(ai, turn);
response.Winning = _board.ValueWon(ai);
if (response.Winning != null)
{
response.PlayerWon = ai;
_playerScore[ai]++;
_state = State.GAME_OVER;
}
}
else
{
// switch between 1 and 2
_currentPlayer = 3 - _currentPlayer;
}
}
if (_board.Full)
{
_playerScore[0]++;
_state = State.GAME_OVER;
}
}
response.Board = _board.Field;
response.PlayerScore = new List<int>(_playerScore);
@ -67,9 +102,14 @@ namespace ProjectGrid
public void Restart(Mode mode)
{
_currentPlayer = new Random().Next(1, 2);
_mode = mode;
_currentPlayer = 1;
_board = new TicTacTocBoard();
_state = State.PLAYING;
_brain = null;
if (Mode.TWO_PLAYER != mode)
_brain = new TicTacTocBrain(_board, 3 - (int)mode);
}

View File

@ -4,14 +4,14 @@ namespace ProjectGrid.TicTacToc
{
public enum Mode
{
TWO_PLAYER,
CROSS_PLAYER,
CIRCLE_PLAYER,
TWO_PLAYER = 0,
CROSS_PLAYER = 1,
CIRCLE_PLAYER = 2,
}
public enum Player
{
EMPTY = 0;
EMPTY = 0,
CROSS = 1,
CIRCLE = 2,
}

View File

@ -47,7 +47,7 @@ namespace ProjectGrid
// Manager
services.AddSingleton<TicTacTocManager>(new TicTacTocManager());
services.AddScoped<TicTacTocTypes, TicTacTocManager>();
services.AddScoped<ITicTacTocManager, TicTacTocManager>();
// DataAccess
services.AddScoped<ITicTacToctRepository, DataAccessContext>();