Skip to content

Commit

Permalink
feat: all tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
nmzgnv committed Oct 18, 2024
1 parent db60afa commit b5bd333
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 22 deletions.
17 changes: 16 additions & 1 deletion ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Game.Domain;
using MongoDB.Driver;

namespace ConsoleApp
{
Expand All @@ -9,11 +10,17 @@ class Program
private readonly IUserRepository userRepo;
private readonly IGameRepository gameRepo;
private readonly Random random = new Random();
private readonly IGameTurnRepository gameTurnRepo;

private Program(string[] args)
{

userRepo = new InMemoryUserRepository();
gameRepo = new InMemoryGameRepository();
var mongoConnectionString = Environment.GetEnvironmentVariable("PROJECT5100_MONGO_CONNECTION_STRING")
?? "mongodb://localhost:27017?maxConnecting=100";
var db = new MongoClient(mongoConnectionString).GetDatabase("game");
gameTurnRepo = new MongoGameTurnRepository(db);
}

public static void Main(string[] args)
Expand Down Expand Up @@ -126,7 +133,8 @@ private bool HandleOneGameTurn(Guid humanUserId)
if (game.HaveDecisionOfEveryPlayer)
{
// TODO: Сохранить информацию о прошедшем туре в IGameTurnRepository. Сформировать информацию о закончившемся туре внутри FinishTurn и вернуть её сюда.
game.FinishTurn();
var turn = game.FinishTurn();
gameTurnRepo.Insert(turn);
}

ShowScore(game);
Expand Down Expand Up @@ -181,6 +189,13 @@ private void ShowScore(GameEntity game)
{
var players = game.Players;
// TODO: Показать информацию про 5 последних туров: кто как ходил и кто в итоге выиграл. Прочитать эту информацию из IGameTurnRepository
var lastGames = gameTurnRepo.GetLastTurns(game.Id).OrderBy(x => x.Turn);
Console.WriteLine(String.Join('\n', lastGames.Select(x =>
{
var winner = x.Winner != 0 ? "Player" + x.Winner : "No one";
return $"Turn number {x.Turn + 1}\nFirstPlayer {x.FirstPlayer} played {x.FirstPlayerDecision}; " +
$"Player2 {x.SecondPlayer} played {x.SecondPlayerDecision}\n{winner} won!";
}).ToList()));
Console.WriteLine($"Score: {players[0].Name} {players[0].Score} : {players[1].Score} {players[1].Name}");
}
}
Expand Down
18 changes: 15 additions & 3 deletions Game/Domain/GameEntity.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes;

namespace Game.Domain
{
public class GameEntity
{
[BsonElement]
private readonly List<Player> players;

public GameEntity(int turnsCount)
: this(Guid.Empty, GameStatus.WaitingToStart, turnsCount, 0, new List<Player>())
{
}

[BsonConstructor]
public GameEntity(Guid id, GameStatus status, int turnsCount, int currentTurnIndex, List<Player> players)
{
Id = id;
Expand All @@ -22,19 +25,24 @@ public GameEntity(Guid id, GameStatus status, int turnsCount, int currentTurnInd
this.players = players;
}

[BsonElement]
public Guid Id
{
get;
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local For MongoDB
private set;
}


[BsonElement]
public IReadOnlyList<Player> Players => players.AsReadOnly();

[BsonElement]
public int TurnsCount { get; }

[BsonElement]
public int CurrentTurnIndex { get; private set; }

[BsonElement]
public GameStatus Status { get; private set; }

public void AddPlayer(UserEntity user)
Expand All @@ -59,6 +67,7 @@ public void Cancel()
Status = GameStatus.Canceled;
}

[BsonElement]
public bool HaveDecisionOfEveryPlayer => Players.All(p => p.Decision.HasValue);

public void SetPlayerDecision(Guid userId, PlayerDecision decision)
Expand Down Expand Up @@ -88,8 +97,11 @@ public GameTurnEntity FinishTurn()
winnerId = player.UserId;
}
}

//TODO Заполнить все внутри GameTurnEntity, в том числе winnerId
var result = new GameTurnEntity();
var result = new GameTurnEntity(Id, CurrentTurnIndex,
players[0].Decision.Value, players[1].Decision.Value,
players[0].UserId, players[1].UserId);
// Это должно быть после создания GameTurnEntity
foreach (var player in Players)
player.Decision = null;
Expand Down
36 changes: 36 additions & 0 deletions Game/Domain/GameTurnEntity.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
using MongoDB.Bson.Serialization.Attributes;
using System;

namespace Game.Domain
{
public class GameTurnEntity
{
//TODO: Придумать какие свойства должны быть в этом классе, чтобы сохранять всю информацию о закончившемся туре.
[BsonConstructor]
public GameTurnEntity(Guid id, int turn, PlayerDecision firstPlayerDecision,
PlayerDecision secondPlayerDecision, Guid firstPlayer, Guid secondPlayer)
{
FirstPlayerDecision = firstPlayerDecision;
SecondPlayerDecision = secondPlayerDecision;
FirstPlayer = firstPlayer;
SecondPlayer = secondPlayer;
Turn = turn;
GameId = id;
Winner = firstPlayerDecision.Beats(secondPlayerDecision)
? 1 : secondPlayerDecision.Beats(firstPlayerDecision)
? 2 : 0;
}
public Guid Id
{
get;
private set;
}
[BsonElement]
public PlayerDecision FirstPlayerDecision { get; }
[BsonElement]
public PlayerDecision SecondPlayerDecision { get; }
[BsonElement]
public Guid FirstPlayer { get; }
[BsonElement]
public Guid SecondPlayer { get; }
[BsonElement]
public Guid GameId { get; }
[BsonElement]
public int Turn { get; }
[BsonElement]
public int Winner { get; }
}
}
5 changes: 5 additions & 0 deletions Game/Domain/IGameTurnRepository.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using System.Collections.Generic;
using System;

namespace Game.Domain
{
public interface IGameTurnRepository
{
// TODO: Спроектировать интерфейс исходя из потребностей ConsoleApp
GameTurnEntity Insert(GameTurnEntity turn);
List<GameTurnEntity> GetLastTurns(Guid gameId);
}
}
19 changes: 12 additions & 7 deletions Game/Domain/MongoGameRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,44 @@ namespace Game.Domain
// TODO Сделать по аналогии с MongoUserRepository
public class MongoGameRepository : IGameRepository
{
private readonly IMongoCollection<GameEntity> gameCollection;
public const string CollectionName = "games";

public MongoGameRepository(IMongoDatabase db)
{
gameCollection = db.GetCollection<GameEntity>(CollectionName);
}

public GameEntity Insert(GameEntity game)
{
throw new NotImplementedException();
gameCollection.InsertOne(game);
return game;
}

public GameEntity FindById(Guid gameId)
{
throw new NotImplementedException();
return gameCollection.Find(g => g.Id == gameId).FirstOrDefault();
}

public void Update(GameEntity game)
{
throw new NotImplementedException();
gameCollection.ReplaceOne(g => g.Id == game.Id, game);
}

// Возвращает не более чем limit игр со статусом GameStatus.WaitingToStart
public IList<GameEntity> FindWaitingToStart(int limit)
{
//TODO: Используй Find и Limit
throw new NotImplementedException();
return gameCollection
.Find(g => g.Status == GameStatus.WaitingToStart)
.Limit(limit)
.ToList();
}

// Обновляет игру, если она находится в статусе GameStatus.WaitingToStart
public bool TryUpdateWaitingToStart(GameEntity game)
{
//TODO: Для проверки успешности используй IsAcknowledged и ModifiedCount из результата
throw new NotImplementedException();
var replaceOneResult = gameCollection.ReplaceOne(g => g.Id == game.Id && g.Status == GameStatus.WaitingToStart, game);
return replaceOneResult.IsAcknowledged && replaceOneResult.ModifiedCount != 0;
}
}
}
27 changes: 27 additions & 0 deletions Game/Domain/MongoGameTurnRepository.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;

namespace Game.Domain
{
public class MongoGameTurnRepository : IGameTurnRepository
{
private readonly IMongoCollection<GameTurnEntity> gameTurnCollection;
public const string CollectionName = "gameTurns";

public GameTurnEntity Insert(GameTurnEntity turn)
{
gameTurnCollection.InsertOne(turn);
return turn;
}

public List<GameTurnEntity> GetLastTurns(Guid gameId)
{
var filter = new BsonDocument("GameId", gameId);
return gameTurnCollection.Find(filter)
.SortByDescending(x => x.Turn)
.Limit(5)
.ToList();
}

public MongoGameTurnRepository(IMongoDatabase db)
{
gameTurnCollection = db.GetCollection<GameTurnEntity>(CollectionName);
}
}
}
33 changes: 22 additions & 11 deletions Game/Domain/MongoUserRepositoty.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using MongoDB.Bson;
using MongoDB.Driver;

namespace Game.Domain
Expand All @@ -11,43 +12,53 @@ public class MongoUserRepository : IUserRepository
public MongoUserRepository(IMongoDatabase database)
{
userCollection = database.GetCollection<UserEntity>(CollectionName);
userCollection.Indexes.CreateOne(new CreateIndexModel<UserEntity>(
Builders<UserEntity>.IndexKeys.Ascending(u => u.Login),
new CreateIndexOptions { Unique = true }));
}

public UserEntity Insert(UserEntity user)
{
//TODO: Ищи в документации InsertXXX.
throw new NotImplementedException();
userCollection.InsertOne(user);
return user;
}

public UserEntity FindById(Guid id)
{
//TODO: Ищи в документации FindXXX
throw new NotImplementedException();
return userCollection.Find(u => u.Id == id).FirstOrDefault();
}

public UserEntity GetOrCreateByLogin(string login)
{
//TODO: Это Find или Insert
throw new NotImplementedException();
var user = userCollection.Find(u => u.Login == login).FirstOrDefault();
if (user != null)
{
return user;
}

return Insert(new UserEntity(Guid.NewGuid(), login, null, null, 0, null));
}

public void Update(UserEntity user)
{
//TODO: Ищи в документации ReplaceXXX
throw new NotImplementedException();
userCollection.ReplaceOne(u => u.Id == user.Id, user);
}

public void Delete(Guid id)
{
throw new NotImplementedException();
userCollection.DeleteOne(u => u.Id == id);
}

// Для вывода списка всех пользователей (упорядоченных по логину)
// страницы нумеруются с единицы
public PageList<UserEntity> GetPage(int pageNumber, int pageSize)
{
//TODO: Тебе понадобятся SortBy, Skip и Limit
throw new NotImplementedException();
var page = userCollection.Find(x => true)
.SortBy(u => u.Login)
.Skip(pageSize * (pageNumber - 1))
.Limit(pageSize)
.ToList();
return new PageList<UserEntity>(page, userCollection.CountDocuments(x => true), pageNumber, pageSize);
}

// Не нужно реализовывать этот метод
Expand Down
4 changes: 4 additions & 0 deletions Game/Domain/Player.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using MongoDB.Bson.Serialization.Attributes;

namespace Game.Domain
{
Expand All @@ -7,17 +8,20 @@ namespace Game.Domain
/// </summary>
public class Player
{
[BsonConstructor]
public Player(Guid userId, string name)
{
UserId = userId;
Name = name;
}

[BsonElement]
public Guid UserId { get; }

/// <summary>
/// Снэпшот имени игрока на момент старта игры. Считайте, что это такое требование к игре.
/// </summary>
[BsonElement]
public string Name { get; }

/// <summary>
Expand Down

0 comments on commit b5bd333

Please sign in to comment.