Added Socket based online Play (Doesnt work)

Signed-off-by: Pablu23 <43807157+Pablu23@users.noreply.github.com>
This commit is contained in:
Pablu23
2021-11-27 13:07:44 +01:00
parent 4c4278edd1
commit 876a593115
4 changed files with 200 additions and 15 deletions

View File

@@ -4,7 +4,7 @@ using TicTacToe.Players;
namespace TicTacToe namespace TicTacToe
{ {
//Class on which every game bases on (Only TicTacToe atm) //Class on which every game bases on (Only TicTacToe atm)
abstract class Game public abstract class Game
{ {
protected readonly List<Player> Players = new List<Player>(); protected readonly List<Player> Players = new List<Player>();
protected readonly Dictionary<Player, int> Scores = new Dictionary<Player, int>(); protected readonly Dictionary<Player, int> Scores = new Dictionary<Player, int>();

View File

@@ -24,7 +24,7 @@ namespace TicTacToe
Console.WriteLine("[S]tart Game"); Console.WriteLine("[S]tart Game");
Console.WriteLine("[E]nd"); Console.WriteLine("[E]nd");
char input = GetCharInput(new[] { 'c', 's', 'e', 'n' }); char input = GetCharInput(new[] { 'c', 's', 'e', 'n', 'o' });
switch (input) switch (input)
{ {
@@ -45,6 +45,21 @@ namespace TicTacToe
break; break;
case 'n': case 'n':
ticTacToe = new TicTacToe(); ticTacToe = new TicTacToe();
break;
case 'o':
string hosting = Console.ReadLine();
var test = new TicTacToeOnline();
if (hosting == "t")
{
test.IsServer(true);
}
else
{
test.IsServer(false);
}
test.StartGame();
break; break;
} }

View File

@@ -4,11 +4,11 @@ using TicTacToe.Players;
namespace TicTacToe namespace TicTacToe
{ {
class TicTacToe : Game public class TicTacToe : Game
{ {
private TicTacToeBoard _board; protected TicTacToeBoard Board;
private bool _gameFinished; protected bool GameFinished;
private void RemovePlayer(Player player) private void RemovePlayer(Player player)
{ {
@@ -74,9 +74,9 @@ namespace TicTacToe
// Check if the game is finished, and if so add Scores and more for LearningAi // Check if the game is finished, and if so add Scores and more for LearningAi
public override void CheckGameState() public override void CheckGameState()
{ {
if (!_board.IsGameFinished(out var winnerState)) return; if (!Board.IsGameFinished(out var winnerState)) return;
_gameFinished = true; GameFinished = true;
// Get the winner (Player? <- ? because the player could be null) // Get the winner (Player? <- ? because the player could be null)
var winner = Players.FirstOrDefault(x => x.Symbol == winnerState); var winner = Players.FirstOrDefault(x => x.Symbol == winnerState);
@@ -88,7 +88,7 @@ namespace TicTacToe
var player = Players.FirstOrDefault(x => x.GetType() == typeof(LearningAiPlayer)); var player = Players.FirstOrDefault(x => x.GetType() == typeof(LearningAiPlayer));
var learningAiPlayer = player as LearningAiPlayer; var learningAiPlayer = player as LearningAiPlayer;
if (learningAiPlayer != null) if (learningAiPlayer != null)
learningAiPlayer.SaveToJson(_board); learningAiPlayer.SaveToJson(Board);
} }
CleanUp(); CleanUp();
} }
@@ -96,14 +96,14 @@ namespace TicTacToe
public override void StartGame() public override void StartGame()
{ {
if (Players.Count != 2) throw new Exception("Not enough, or too many Players"); if (Players.Count != 2) throw new Exception("Not enough, or too many Players");
_board = new TicTacToeBoard(); Board = new TicTacToeBoard();
// Draw the Board so the first Player can see it // Draw the Board so the first Player can see it
_board.DrawBoard(); Board.DrawBoard();
_gameFinished = false; GameFinished = false;
int round = 0; int round = 0;
while (_gameFinished != true) while (GameFinished != true)
{ {
// For both Players // For both Players
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@@ -113,14 +113,14 @@ namespace TicTacToe
bool placed; bool placed;
do do
{ {
placed = _board.TryPlace(Players[i].MakeMove(_board), Players[i], round); placed = Board.TryPlace(Players[i].MakeMove(Board), Players[i], round);
} while (!placed); } while (!placed);
round++; round++;
_board.DrawBoard(); Board.DrawBoard();
CheckGameState(); CheckGameState();
//Dont let the second Player make his turn if the game is already finished //Dont let the second Player make his turn if the game is already finished
if (_gameFinished) break; if (GameFinished) break;
} }
} }
} }

View File

@@ -0,0 +1,170 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json;
using TicTacToe.Players;
namespace TicTacToe
{
public class TicTacToeOnline : TicTacToe
{
private bool _isServer = false;
private int _port = 6969;
private string _ipAddress = "127.0.0.1";
private Socket _client;
private int _clientPlayerId = -1;
public override void AddPlayer(Player player)
{
if (player.GetType() != typeof(HumanPlayer))
throw new Exception("Online Play is only available with human Players");
base.AddPlayer(player);
}
public void IsServer(bool x)
{
_isServer = x;
}
public override void StartGame()
{
if (_isServer)
{
StartServer();
if (Players.Count != 2) throw new Exception("Not enough, or too many Players");
Board = new TicTacToeBoard();
string ticTacToeBoardJson = JsonConvert.SerializeObject(Board);
SendData(ticTacToeBoardJson);
}
else
{
ConnectToServer();
if (Players.Count != 2) throw new Exception("Not enough, or too many Players");
string ticTacToeBoardJson = ReceiveData();
Board = JsonConvert.DeserializeObject<TicTacToeBoard>(ticTacToeBoardJson);
}
Board.DrawBoard();
GameFinished = false;
int round = 0;
while (GameFinished != true)
{
// For both Players
for (int i = 0; i < 2; i++)
{
if (i == _clientPlayerId)
{
bool placed;
do
{
placed = Board.TryPlace(Players[i].MakeMove(Board), Players[i], round);
} while (!placed);
string newBoardJson = JsonConvert.SerializeObject(Board);
SendData(newBoardJson);
}
else
{
string data = ReceiveData();
Board = JsonConvert.DeserializeObject<TicTacToeBoard>(data);
}
round++;
Board.DrawBoard();
CheckGameState();
//Dont let the second Player make his turn if the game is already finished
if (GameFinished) break;
}
}
}
private void SendData(string data)
{
data += "<EOF>";
Console.WriteLine("Sending Data: " + data);
byte[] bytes = Encoding.ASCII.GetBytes(data);
_client.Send(bytes);
}
private string ReceiveData()
{
string data = null;
byte[] bytes = null;
Console.WriteLine("Receiving Data");
while (true)
{
bytes = new byte[1024];
int bytesRec = _client.Receive(bytes);
data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
Console.WriteLine("Data: " + data);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Data Received, returning");
return data;
}
private void ConnectToServer()
{
IPHostEntry host = Dns.GetHostEntry(_ipAddress);
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, _port);
_client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_client.Connect(remoteEndPoint);
Console.WriteLine("connected");
string data = ReceiveData();
HumanPlayer opponent = JsonConvert.DeserializeObject<HumanPlayer>(data);
AddPlayer(opponent);
HumanPlayer player = new HumanPlayer("Client",
opponent.Symbol == FieldState.PlayerX ? FieldState.PlayerO : FieldState.PlayerX);
AddPlayer(player);
string playerJson = JsonConvert.SerializeObject(player);
SendData(playerJson);
_clientPlayerId = 0;
}
private void StartServer()
{
IPHostEntry host = Dns.GetHostEntry(_ipAddress);
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, _port);
Socket server = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
server.Bind(localEndPoint);
server.Listen(1);
_client = server.Accept();
Console.WriteLine("A Client connected");
var player = new HumanPlayer("Server", FieldState.PlayerX);
AddPlayer(player);
string playerJson = JsonConvert.SerializeObject(player);
SendData(playerJson);
string data = ReceiveData();
var opponent = JsonConvert.DeserializeObject<HumanPlayer>(data);
AddPlayer(opponent);
_clientPlayerId = 1;
}
}
}