got c# backend working (more or less..)

This commit is contained in:
Shuozhe 2021-06-26 00:25:59 +02:00
parent 3d3ce211b3
commit 1ef728dc50
11 changed files with 216 additions and 93 deletions

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ProjectGrid.Data; using ProjectGrid.Data;
using ProjectGrid.Models;
namespace ProjectGrid.Controllers namespace ProjectGrid.Controllers
{ {
@ -16,30 +17,31 @@ namespace ProjectGrid.Controllers
private readonly ILogger<TicTacTocController> _logger; private readonly ILogger<TicTacTocController> _logger;
//static readonly Models.IUserRepository repository = new Models.UserRepository(); private readonly TicTacTocManager _manager;
private readonly ITicTacToctRepository repository;
public TicTacTocController(ILogger<TicTacTocController> logger, DataAccessContext context) public TicTacTocController(ILogger<TicTacTocController> logger, TicTacTocManager manager)
{ {
_logger = logger; _logger = logger;
repository = context; _manager = manager;
} }
[HttpGet] [HttpGet]
[Route("api/ttt/GetBoard")] [Route("api/ttt/GetBoard")]
public Models.TicTacTocBoard GetBoard() public TicTacTocResponse GetBoard()
{ {
return repository.GetBoard(); _logger.LogTrace("GetBoard called.");
return _manager.GetResponse();
} }
[HttpPost] [HttpPost]
[Route("api/ttt/SetPiece")] [Route("api/ttt/SetPiece")]
[Consumes("application/json")] [Consumes("application/json")]
public Models.UserModel PostMove(Models.UserModel item) public TicTacTocResponse PostMove(TicTacTocRequest move)
{ {
return repository.Add(item); _logger.LogTrace($"PostMove called. {move.DebugString()}");
_manager.NextMove(move);
return _manager.GetResponse(move.Player);
} }
} }
} }

View File

@ -10,7 +10,7 @@ namespace ProjectGrid.Data
public partial class DataAccessContext : ITicTacToctRepository public partial class DataAccessContext : ITicTacToctRepository
{ {
public bool AddPiece(TicTacTocMove user) public bool AddPiece(TicTacTocRequest request)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }

View File

@ -6,6 +6,6 @@ namespace ProjectGrid.Data
{ {
TicTacTocBoard GetBoard(); TicTacTocBoard GetBoard();
bool AddPiece(TicTacTocMove user); bool AddPiece(TicTacTocRequest user);
} }
} }

92
Logic/TicTacTocBoard.cs Normal file
View File

@ -0,0 +1,92 @@
using System.Collections.Generic;
using System.Diagnostics;
namespace ProjectGrid.Models
{
/// <summary>
/// Holds data for a TicTacTocBoard
/// 0: empty field, > 0 players
/// </summary>
public class TicTacTocBoard
{
private List<int> _field;
public List<int> Field => _field;
private int _lastSetValue;
public int LastSetValue => _lastSetValue;
private int PosToIdx(int x, int y)
{
Debug.Assert(x >= 0 && x <= 3
&& y >= 0 && y <= 3,
$"{x}:{y} outside of playarea!");
return x + y * 3;
}
private int GetField(int x, int y) => _field[PosToIdx(x, y)];
private void SetField(int value, int x, int y)
{
_field[PosToIdx(x, y)] = value;
_lastSetValue = value;
}
// 0 1 2
// 3 4 5
// 6 7 8
private static readonly int[,] _winning = new int[,] {
{ 0, 1, 2 },
{ 3, 4, 5 },
{ 6, 7 ,8 },
{ 0, 3 ,6 },
{ 1, 4 ,7 },
{ 2, 5 ,8 },
{ 0, 4 ,8 },
{ 2, 4 ,6 },
};
public TicTacTocBoard()
{
_field = new List<int>(new int[9] {
0, 0, 0,
0, 0, 0,
0, 0, 0,
});
_lastSetValue = 0;
}
public bool SetFieldValue(int value, int x, int y, bool force = false)
{
int field = GetField(x, y);
if (0 == field || force)
{
SetField(value, x, y);
return true;
}
return false;
}
public bool ValueWon(int value)
{
Debug.Assert(value > 0, "ValueWon called for Empty field 0");
for (int x = 0; x < _winning.GetLength(0); x++)
{
bool won = true;
for (int y = 0; y < _winning.GetLength(1); y++)
{
if (_field[_winning[x, y]] != value)
{
won = false;
break;
}
}
if (won)
return true;
}
return false;
}
}
}

View File

@ -5,16 +5,41 @@ using System;
namespace ProjectGrid namespace ProjectGrid
{ {
public class TicTacTocManager public interface ITicTacTocManager
{
public bool NextMove(TicTacTocRequest move);
public TicTacTocResponse GetResponse(int player = 0);
}
public class TicTacTocManager : ITicTacTocManager
{ {
private ITicTacToctRepository _repo; private ITicTacToctRepository _repo;
private TicTacTocBoard _board; private TicTacTocBoard _board;
public TicTacTocBoard Board => _board;
public TicTacTocManager(ITicTacToctRepository repo) public TicTacTocManager(/*ITicTacToctRepository repo*/)
{ {
_repo = repo; //_repo = repo;
_board = new TicTacTocBoard();
}
public bool NextMove(TicTacTocRequest move)
{
return _board.SetFieldValue(move.Player, move.PosX, move.PosY);
}
public TicTacTocResponse GetResponse(int player = 0)
{
TicTacTocResponse response = new TicTacTocResponse();
if (player > 0 && _board.ValueWon(player))
response.PlayerWon = player;
response.Board = _board.Field;
return response;
} }
} }
} }

View File

@ -1,13 +0,0 @@
namespace ProjectGrid.Models
{
public class TicTacTocBoard
{
public int Id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
}
}

View File

@ -1,13 +0,0 @@
namespace ProjectGrid.Models
{
public class TicTacTocMove
{
public int Id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace ProjectGrid.Models
{
public class TicTacTocRequest
{
public int PosX { get; set; }
public int PosY { get; set; }
public int Player { get; set; }
public string DebugString() => $"Pos: [{PosX}|{PosY}; Player: {Player}";
}
}

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace ProjectGrid.Models
{
public class TicTacTocResponse
{
public List<int> Board { get; set; }
public int PlayerWon { get; set; }
}
}

View File

@ -30,7 +30,6 @@ namespace ProjectGrid
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "An error occurred while seeding the database."); _logger.LogError(ex, "An error occurred while seeding the database.");
} }
} }

View File

@ -15,58 +15,65 @@ using ProjectGrid.Data;
namespace ProjectGrid namespace ProjectGrid
{ {
public class Startup public class Startup
{
ILogger _logger;
public Startup()
{ {
ILogger _logger; Configuration = new ConfigurationBuilder()
.AddJsonFile("appSettings.json") // Get Connectionstring from appsetting.json
public Startup() .Build();
{
Configuration = new ConfigurationBuilder()
.AddJsonFile("appSettings.json") // Get Connectionstring from appsetting.json
.Build();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
// Cant log here..
//_logger.LogInformation($"Try to connect to Database with {connectionString}");
services.AddDbContext<DataAccessContext>(options => options.UseSqlServer(connectionString));
//_logger.LogInformation($"DataAccessContext registered with {connectionString}");
// TODO: for Testing
//services.AddDatabaseDeveloperPageExceptionFilter();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ProjectGrid", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
_logger = logger;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProjectGrid v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
} }
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
// Cant log here..
//_logger.LogInformation($"Try to connect to Database with {connectionString}");
services.AddDbContext<DataAccessContext>(options => options.UseSqlServer(connectionString));
//_logger.LogInformation($"DataAccessContext registered with {connectionString}");
// TODO: for Testing
//services.AddDatabaseDeveloperPageExceptionFilter();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ProjectGrid", Version = "v1" });
});
// Manager
services.AddSingleton<TicTacTocManager>(new TicTacTocManager());
services.AddScoped<ITicTacTocManager, TicTacTocManager>();
// DataAccess
services.AddScoped<ITicTacToctRepository, DataAccessContext>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
_logger = logger;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProjectGrid v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
} }