added Brain for second Player
This commit is contained in:
parent
0edb73d8a3
commit
1a110b213a
|
|
@ -35,10 +35,10 @@ namespace ProjectGrid.Controllers
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/ttt/Restart")]
|
[Route("api/ttt/Restart")]
|
||||||
public void RestartGame()
|
public void RestartGame(TicTacToc.Mode mode = TicTacToc.Mode.CROSS_PLAYER)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("RestartGame called.");
|
_logger.LogTrace("RestartGame called.");
|
||||||
_manager.Restart();
|
_manager.Restart(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace ProjectGrid.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Models.TicTacTocBrain GetBoard()
|
public TicTacTocBoard GetBoard()
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ namespace ProjectGrid.Data
|
||||||
{
|
{
|
||||||
public interface ITicTacToctRepository
|
public interface ITicTacToctRepository
|
||||||
{
|
{
|
||||||
TicTacTocBrain GetBoard();
|
TicTacTocBoard GetBoard();
|
||||||
|
|
||||||
bool AddPiece(TicTacTocRequest user);
|
bool AddPiece(TicTacTocRequest user);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using ProjectGrid.Models;
|
||||||
using ProjectGrid.TicTacToc;
|
using ProjectGrid.TicTacToc;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace ProjectGrid.AI
|
namespace ProjectGrid.AI
|
||||||
|
|
@ -13,10 +14,10 @@ namespace ProjectGrid.AI
|
||||||
|
|
||||||
private List<int> _prio;
|
private List<int> _prio;
|
||||||
|
|
||||||
public TicTacTocBrain(TicTacTocBoard board, Player player)
|
public TicTacTocBrain(TicTacTocBoard board, int player)
|
||||||
{
|
{
|
||||||
_board = board;
|
_board = board;
|
||||||
_player = (int)player;
|
_player = player;
|
||||||
|
|
||||||
var rand = new Random();
|
var rand = new Random();
|
||||||
_prio = (new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }).OrderBy(i => rand.Next()).ToList();
|
_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()
|
public int Turn()
|
||||||
{
|
{
|
||||||
if (_board.Field[5] == (int)Player.EMPTY)
|
if (_board.Field[4] == (int)Player.EMPTY)
|
||||||
{
|
{
|
||||||
//_board.SetFieldValue(_player, 5);
|
//_board.SetFieldValue(_player, 5);
|
||||||
return 5;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int blocking = -1;
|
||||||
for (int x = 0; x < TicTacTocBoard._winning.GetLength(0); x++)
|
for (int x = 0; x < TicTacTocBoard._winning.GetLength(0); x++)
|
||||||
{
|
{
|
||||||
var _1 = TicTacTocBoard._winning[x, 0];
|
var _1 = _board.Field[TicTacTocBoard._winning[x, 0]];
|
||||||
var _2 = TicTacTocBoard._winning[x, 1];
|
var _2 = _board.Field[TicTacTocBoard._winning[x, 1]];
|
||||||
var _3 = TicTacTocBoard._winning[x, 2];
|
var _3 = _board.Field[TicTacTocBoard._winning[x, 2]];
|
||||||
|
|
||||||
int result = Match2(_1, _2, _3);
|
// any field set?
|
||||||
if (result > 0)
|
if (_1 + _2 + _3 == 0)
|
||||||
{
|
continue;
|
||||||
//_board.SetFieldValue(_player, );
|
|
||||||
return TicTacTocBoard._winning[x, result];
|
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)
|
foreach (var i in _prio)
|
||||||
if (_board.Field[i] == 0)
|
if (_board.Field[i] == 0)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
|
Debug.Fail("Brain found no valid move!");
|
||||||
return -1;
|
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)
|
(int win, int block) result = (-1, -1);
|
||||||
return 3;
|
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 result;
|
||||||
return 2;
|
|
||||||
|
|
||||||
if (_1 == 0 && _2 == _player && _3 == _player)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,8 @@ namespace ProjectGrid.Models
|
||||||
private int _lastSetValue;
|
private int _lastSetValue;
|
||||||
public int LastSetValue => _lastSetValue;
|
public int LastSetValue => _lastSetValue;
|
||||||
|
|
||||||
|
public bool Full => !!!_field.Contains(0);
|
||||||
|
|
||||||
private int PosToIdx(int x, int y)
|
private int PosToIdx(int x, int y)
|
||||||
{
|
{
|
||||||
Debug.Assert(x >= 0 && x <= 3
|
Debug.Assert(x >= 0 && x <= 3
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using ProjectGrid.AI;
|
||||||
using ProjectGrid.Models;
|
using ProjectGrid.Models;
|
||||||
using ProjectGrid.TicTacToc;
|
using ProjectGrid.TicTacToc;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -22,6 +23,9 @@ namespace ProjectGrid
|
||||||
}
|
}
|
||||||
|
|
||||||
private State _state;
|
private State _state;
|
||||||
|
private Mode _mode;
|
||||||
|
|
||||||
|
private TicTacTocBrain _brain;
|
||||||
|
|
||||||
//private ITicTacToctRepository _repo;
|
//private ITicTacToctRepository _repo;
|
||||||
|
|
||||||
|
|
@ -36,7 +40,7 @@ namespace ProjectGrid
|
||||||
{
|
{
|
||||||
//_repo = repo;
|
//_repo = repo;
|
||||||
_currentPlayer = 1;
|
_currentPlayer = 1;
|
||||||
Restart(Mode.TWO_PLAYER);
|
Restart(Mode.CROSS_PLAYER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TicTacTocResponse NextMove(TicTacTocRequest move)
|
public TicTacTocResponse NextMove(TicTacTocRequest move)
|
||||||
|
|
@ -45,19 +49,50 @@ namespace ProjectGrid
|
||||||
|
|
||||||
if (_state != State.GAME_OVER)
|
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)
|
|
||||||
{
|
{
|
||||||
response.PlayerWon = _currentPlayer;
|
response.Winning = _board.ValueWon(_currentPlayer);
|
||||||
_state = State.GAME_OVER;
|
if (_currentPlayer > 0 && response.Winning != null)
|
||||||
_playerScore[_currentPlayer]++;
|
{
|
||||||
|
response.PlayerWon = _currentPlayer;
|
||||||
|
_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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch between 1 and 2
|
if (_board.Full)
|
||||||
_currentPlayer = 3 - _currentPlayer;
|
{
|
||||||
|
_playerScore[0]++;
|
||||||
|
_state = State.GAME_OVER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Board = _board.Field;
|
response.Board = _board.Field;
|
||||||
response.PlayerScore = new List<int>(_playerScore);
|
response.PlayerScore = new List<int>(_playerScore);
|
||||||
|
|
||||||
|
|
@ -67,9 +102,14 @@ namespace ProjectGrid
|
||||||
|
|
||||||
public void Restart(Mode mode)
|
public void Restart(Mode mode)
|
||||||
{
|
{
|
||||||
_currentPlayer = new Random().Next(1, 2);
|
_mode = mode;
|
||||||
|
_currentPlayer = 1;
|
||||||
_board = new TicTacTocBoard();
|
_board = new TicTacTocBoard();
|
||||||
_state = State.PLAYING;
|
_state = State.PLAYING;
|
||||||
|
|
||||||
|
_brain = null;
|
||||||
|
if (Mode.TWO_PLAYER != mode)
|
||||||
|
_brain = new TicTacTocBrain(_board, 3 - (int)mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ namespace ProjectGrid.TicTacToc
|
||||||
{
|
{
|
||||||
public enum Mode
|
public enum Mode
|
||||||
{
|
{
|
||||||
TWO_PLAYER,
|
TWO_PLAYER = 0,
|
||||||
CROSS_PLAYER,
|
CROSS_PLAYER = 1,
|
||||||
CIRCLE_PLAYER,
|
CIRCLE_PLAYER = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Player
|
public enum Player
|
||||||
{
|
{
|
||||||
EMPTY = 0;
|
EMPTY = 0,
|
||||||
CROSS = 1,
|
CROSS = 1,
|
||||||
CIRCLE = 2,
|
CIRCLE = 2,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace ProjectGrid
|
||||||
|
|
||||||
// Manager
|
// Manager
|
||||||
services.AddSingleton<TicTacTocManager>(new TicTacTocManager());
|
services.AddSingleton<TicTacTocManager>(new TicTacTocManager());
|
||||||
services.AddScoped<TicTacTocTypes, TicTacTocManager>();
|
services.AddScoped<ITicTacTocManager, TicTacTocManager>();
|
||||||
|
|
||||||
// DataAccess
|
// DataAccess
|
||||||
services.AddScoped<ITicTacToctRepository, DataAccessContext>();
|
services.AddScoped<ITicTacToctRepository, DataAccessContext>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue