diff --git a/TicTacToe/Game.cs b/TicTacToe/Game.cs index 940f690..ad59131 100644 --- a/TicTacToe/Game.cs +++ b/TicTacToe/Game.cs @@ -4,7 +4,7 @@ using TicTacToe.Players; namespace TicTacToe { //Class on which every game bases on (Only TicTacToe atm) - abstract class Game + public abstract class Game { protected readonly List Players = new List(); protected readonly Dictionary Scores = new Dictionary(); diff --git a/TicTacToe/Program.cs b/TicTacToe/Program.cs index 409a92b..73bfed1 100644 --- a/TicTacToe/Program.cs +++ b/TicTacToe/Program.cs @@ -24,7 +24,7 @@ namespace TicTacToe Console.WriteLine("[S]tart Game"); Console.WriteLine("[E]nd"); - char input = GetCharInput(new[] { 'c', 's', 'e', 'n' }); + char input = GetCharInput(new[] { 'c', 's', 'e', 'n', 'o' }); switch (input) { @@ -45,6 +45,21 @@ namespace TicTacToe break; case 'n': 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; } diff --git a/TicTacToe/TicTacToe.cs b/TicTacToe/TicTacToe.cs index 11207ed..d7073d7 100644 --- a/TicTacToe/TicTacToe.cs +++ b/TicTacToe/TicTacToe.cs @@ -4,11 +4,11 @@ using TicTacToe.Players; 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) { @@ -74,9 +74,9 @@ namespace TicTacToe // Check if the game is finished, and if so add Scores and more for LearningAi 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) var winner = Players.FirstOrDefault(x => x.Symbol == winnerState); @@ -88,7 +88,7 @@ namespace TicTacToe var player = Players.FirstOrDefault(x => x.GetType() == typeof(LearningAiPlayer)); var learningAiPlayer = player as LearningAiPlayer; if (learningAiPlayer != null) - learningAiPlayer.SaveToJson(_board); + learningAiPlayer.SaveToJson(Board); } CleanUp(); } @@ -96,14 +96,14 @@ namespace TicTacToe public override void StartGame() { 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 - _board.DrawBoard(); - _gameFinished = false; + Board.DrawBoard(); + GameFinished = false; int round = 0; - while (_gameFinished != true) + while (GameFinished != true) { // For both Players for (int i = 0; i < 2; i++) @@ -113,14 +113,14 @@ namespace TicTacToe bool placed; do { - placed = _board.TryPlace(Players[i].MakeMove(_board), Players[i], round); + placed = Board.TryPlace(Players[i].MakeMove(Board), Players[i], round); } while (!placed); round++; - _board.DrawBoard(); + Board.DrawBoard(); CheckGameState(); //Dont let the second Player make his turn if the game is already finished - if (_gameFinished) break; + if (GameFinished) break; } } } diff --git a/TicTacToe/TicTacToeOnline.cs b/TicTacToe/TicTacToeOnline.cs new file mode 100644 index 0000000..c8ee594 --- /dev/null +++ b/TicTacToe/TicTacToeOnline.cs @@ -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(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(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 += ""; + 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("") > -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(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(data); + + AddPlayer(opponent); + _clientPlayerId = 1; + } + } +} \ No newline at end of file