added Brain for second Player
This commit is contained in:
parent
0edb73d8a3
commit
1a110b213a
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace ProjectGrid.Data
|
|||
}
|
||||
|
||||
|
||||
public Models.TicTacTocBrain GetBoard()
|
||||
public TicTacTocBoard GetBoard()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace ProjectGrid.Data
|
|||
{
|
||||
public interface ITicTacToctRepository
|
||||
{
|
||||
TicTacTocBrain GetBoard();
|
||||
TicTacTocBoard GetBoard();
|
||||
|
||||
bool AddPiece(TicTacTocRequest user);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,19 +49,50 @@ namespace ProjectGrid
|
|||
|
||||
if (_state != State.GAME_OVER)
|
||||
{
|
||||
_board.SetFieldValue(_currentPlayer, move.Field);
|
||||
|
||||
response.Winning = _board.ValueWon(_currentPlayer);
|
||||
if (_currentPlayer > 0 && response.Winning != null)
|
||||
if (_board.SetFieldValue(_currentPlayer, move.Field))
|
||||
{
|
||||
response.PlayerWon = _currentPlayer;
|
||||
_state = State.GAME_OVER;
|
||||
_playerScore[_currentPlayer]++;
|
||||
response.Winning = _board.ValueWon(_currentPlayer);
|
||||
if (_currentPlayer > 0 && response.Winning != null)
|
||||
{
|
||||
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
|
||||
_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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue