Skip to content

Commit

Permalink
Ready for sheffield
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBetteridge committed Jan 14, 2020
1 parent 5e6bd33 commit 09a54ed
Show file tree
Hide file tree
Showing 32 changed files with 583 additions and 223 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

Connect4Database.jfm

# User-specific files
*.suo
*.user
Expand Down
Binary file added Connect4 - Sheffield.pptx
Binary file not shown.
69 changes: 39 additions & 30 deletions Connect4.AlphaBeta/API.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Connect4.ExampleBot
{
internal static class API
public class API
{
private readonly HttpClient _httpClient;

public API(Uri serverUri)
{
_httpClient = new HttpClient
{
BaseAddress = serverUri
};
}
/// <summary>
/// Get the current state of the game
/// </summary>
/// <param name="playerID"></param>
/// <param name="serverURL"></param>
/// <returns></returns>
internal static Game GetGame(Guid playerID, string serverURL)
internal async Task<Game> GetGame(Guid playerID)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(serverURL);

var httpResponseMessage = httpClient.GetAsync($"api/GameState?playerID={playerID}").Result;
var httpResponseMessage = await _httpClient.GetAsync($"/api/GameState/{playerID}");
if (!httpResponseMessage.IsSuccessStatusCode)
{
// Something has gone wrong
var errors = httpResponseMessage.Content.ReadAsStringAsync().Result;
var errors = await httpResponseMessage.Content.ReadAsStringAsync();
throw new Exception(string.Format("Failed to call {0}. Status {1}. Reason {2}. {3}", "GameState", (int)httpResponseMessage.StatusCode, httpResponseMessage.ReasonPhrase, errors));
}
else
{
// All good
var result = httpResponseMessage.Content.ReadAsAsync<Game>().Result;
var result = await httpResponseMessage.Content.ReadAsJsonAsync<Game>();
return result;
}
}
Expand All @@ -36,14 +42,16 @@ internal static Game GetGame(Guid playerID, string serverURL)
/// </summary>
/// <param name="TeamName"></param>
/// <param name="teamPassword"></param>
/// <param name="serverURL"></param>
/// <returns></returns>
internal static Guid RegisterTeam(string TeamName, string teamPassword, string serverURL)
internal async Task<Guid> RegisterTeam(string teamName, string teamPassword)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(serverURL);
var data = new
{
TeamName = teamName,
Password = teamPassword,
};

var httpResponseMessage = httpClient.PostAsync($"api/Register?teamName={TeamName}&password={teamPassword}", null).Result;
var httpResponseMessage = await _httpClient.PostAsJsonAsync($"/api/Register", data).ConfigureAwait(false);
if (!httpResponseMessage.IsSuccessStatusCode)
{
// Something has gone wrong
Expand All @@ -53,28 +61,30 @@ internal static Guid RegisterTeam(string TeamName, string teamPassword, string s
else
{
// All good
var result = httpResponseMessage.Content.ReadAsAsync<string>().Result;
return new Guid(result);
var result = await httpResponseMessage.Content.ReadAsJsonAsync<Guid>().ConfigureAwait(false);
return result;
}

}

/// <summary>
/// Plays a move. ColumnNumber should be between 0 and 6
/// </summary>
/// <param name="playerID"></param>
/// <param name="serverURL"></param>
/// <param name="columnNumber"></param>
internal static void MakeMove(Guid playerID, string serverURL, int columnNumber, string teamPassword)
internal async Task MakeMove(Guid playerID, int columnNumber, string teamPassword)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(serverURL);
var data = new
{
playerID = playerID,
columnNumber = columnNumber,
password = teamPassword
};

var httpResponseMessage = httpClient.PostAsync($"api/MakeMove?playerID={playerID}&columnNumber={columnNumber}&password={teamPassword}", null).Result;
var httpResponseMessage = await _httpClient.PostAsJsonAsync($"/api/MakeMove", data);
if (!httpResponseMessage.IsSuccessStatusCode)
{
// Something has gone wrong
var errors = httpResponseMessage.Content.ReadAsStringAsync().Result;
var errors = await httpResponseMessage.Content.ReadAsStringAsync();
throw new Exception(string.Format("Failed to call {0}. Status {1}. Reason {2}. {3}", "MakeMove", (int)httpResponseMessage.StatusCode, httpResponseMessage.ReasonPhrase, errors));
}
}
Expand All @@ -84,21 +94,20 @@ internal static void MakeMove(Guid playerID, string serverURL, int columnNumber,
/// however be swapped (red => yellow and yellow => red)
/// </summary>
/// <param name="playerID"></param>
/// <param name="serverURL"></param>
internal static void NewGame(Guid playerID, string serverURL)
internal async Task NewGame(Guid playerID)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(serverURL);
var data = new
{
playerId = playerID,
};

var httpResponseMessage = httpClient.PostAsync($"api/NewGame?playerID={playerID}", null).Result;
var httpResponseMessage = await _httpClient.PostAsJsonAsync($"/api/NewGame", data).ConfigureAwait(false);
if (!httpResponseMessage.IsSuccessStatusCode)
{
// Something has gone wrong
var errors = httpResponseMessage.Content.ReadAsStringAsync().Result;
throw new Exception(string.Format("Failed to call {0}. Status {1}. Reason {2}. {3}", "NewGame", (int)httpResponseMessage.StatusCode, httpResponseMessage.ReasonPhrase, errors));
}

}

}
}
1 change: 1 addition & 0 deletions Connect4.AlphaBeta/Connect4.AlphaBeta.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<ItemGroup>
<Compile Include="API.cs" />
<Compile Include="Game.cs" />
<Compile Include="HttpClientExtensions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down
24 changes: 24 additions & 0 deletions Connect4.AlphaBeta/HttpClientExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Connect4.ExampleBot
{
public static class HttpClientExtensions
{
public static Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient httpClient, string url, T data)
{
var dataAsString = JsonConvert.SerializeObject(data);
var content = new StringContent(dataAsString);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return httpClient.PostAsync(url, content);
}

public static async Task<T> ReadAsJsonAsync<T>(this HttpContent content)
{
var dataAsString = await content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(dataAsString);
}
}
}
16 changes: 9 additions & 7 deletions Connect4.AlphaBeta/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Program

private const int ROWS = 6;
private const int COLUMNS = 7;
private static API _api;

private static int WorkOutMove(Game game, Guid playerID)
{
Expand Down Expand Up @@ -363,17 +364,17 @@ private static bool IsValidMove(Game game, int column)
return (game.Cells[column, ROWS - 1] == CellContent.Empty);
}

private static void MakeMove(Game game, Guid playerID, string serverURL)
private static async Task MakeMove(API api, Game game, Guid playerID)
{
var columnToPlayIn = WorkOutMove(game, playerID);
API.MakeMove(playerID, serverURL, columnToPlayIn, teamPassword);
await api.MakeMove(playerID, columnToPlayIn, teamPassword);

//Console.WriteLine("Press to play");
//Console.ReadKey(true);
}


static void Main(string[] args)
static async Task Main(string[] args)
{

var testGame = new Game();
Expand All @@ -390,15 +391,16 @@ static void Main(string[] args)
// First stage is to register your team name. This gives
// you back a TeamID which you need to use in all following
// class.
var playerID = API.RegisterTeam(teamName, teamPassword, serverURL);
_api = new API(new Uri(serverURL));
var playerID = await _api.RegisterTeam(teamName, teamPassword);
Console.WriteLine($"PlayerID is {playerID}");


// This is the main game loop
var gameIsComplete = false;
while (!gameIsComplete)
{
var game = API.GetGame(playerID, serverURL);
var game = await _api.GetGame(playerID);

switch (game.CurrentState)
{
Expand All @@ -415,14 +417,14 @@ static void Main(string[] args)
case GameState.RedToPlay:
if (game.RedPlayerID == playerID)
{
MakeMove(game, playerID, serverURL);
await MakeMove(_api, game, playerID);
}
break;

case GameState.YellowToPlay:
if (game.YellowPlayerID == playerID)
{
MakeMove(game, playerID, serverURL);
await MakeMove(_api, game, playerID);
}
break;

Expand Down
8 changes: 4 additions & 4 deletions Connect4.Core/Connect4.Core.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Connect4.Core/Controllers/GameStateController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public GameStateController(Database database, GameCreator gameCreator)
/// <remarks>
/// Sample request:
///
/// GET api/GameState/abcedf
/// GET /api/GameState/abcedf
///
/// </remarks>
/// <returns>The state of the game</returns>
Expand Down
2 changes: 1 addition & 1 deletion Connect4.Core/Controllers/MakeMoveController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public MakeMoveController(Database database, BotCreator botCreator, PasswordHash
/// <remarks>
/// Sample request:
///
/// POST api/MakeMove
/// POST /api/MakeMove
/// {
/// "PlayerID" : "abcde..."
/// "Password" : "secret"
Expand Down
2 changes: 1 addition & 1 deletion Connect4.Core/Controllers/NewGameController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public NewGameController(Database database, GameCreator gameCreator, BotCreator
/// <remarks>
/// Sample request:
///
/// POST api/NewGame
/// POST /api/NewGame
///
/// {
/// "playerID" : "abcdef...",
Expand Down
8 changes: 6 additions & 2 deletions Connect4.Core/Controllers/RegisterController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public RegisterController(Database database, GameCreator gameCreator, PasswordHa
/// <remarks>
/// Sample request:
///
/// POST api/Register
/// POST /api/Register
///
/// {
/// "teamName" : "David",
Expand All @@ -48,7 +48,11 @@ public async Task<ActionResult<Guid>> POST([FromBody] RegisterTeamViewModel regi

// Reload the player
var reloadedPlayer = await _database.LoadPlayer(player.ID);
if (reloadedPlayer == null) return BadRequest("No player with this ID exists");
if (reloadedPlayer == null)
{
var details = new ValidationProblemDetails { Detail = $"No player with the ID {player.ID} exists" };
return ValidationProblem(details);
}

if (!_passwordHashing.CompareHashes(registerTeamViewModel.Password, reloadedPlayer.Password))
{
Expand Down
2 changes: 1 addition & 1 deletion Connect4.Core/Services/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public async Task<List<Game>> GetAllGames()
}
return result;
}
public async Task<Game> LoadGame(Guid gameID)
public async Task<Game?> LoadGame(Guid gameID)
{
using (var cn = new SqlConnection(_settings.ConnectionString))
{
Expand Down
Loading

0 comments on commit 09a54ed

Please sign in to comment.