介绍:
两人在线对弈的策略型棋类游戏
五子棋起源于中国,是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
游戏功能说明
- 分为客户端和服务端,服务端控制业务逻辑,客户端展示及交互
- 客户端功能包含: 找棋友,重新开始,悔棋,认输,逃跑,棋谱记录,eabei聊天室
2.1 找棋友: 通过服务器随机分配一名对手,
2.2 重新开始: 在完成一局之后,如果还想和该对手再来一局,可以点击重新开始,双方都要重新开始才能开始新一局游戏。反之则不能开始;
2.3 悔棋: 当一名对手下了一子,如果下得不对,想悔一步,则点击悔棋,如果对方想悔棋则是不能的,悔棋可以连续返回到最初开始的状态;
2.4 认输: 当觉得自己不能战胜对方时,点击认输,这时需要对手的同意才能完成认输过程。
2.5 逃跑: 当匹配到对手后,在任一时刻都可以逃跑。
2.6 棋谱记录: 棋谱记录了上一次下棋的过程,并且可以进行回放,回放方式设计了2种模式: 一种是自动回放,另一种是手动回放;
2.7 Eabei聊天室: 聊天目前只能在匹配对手成功后,都可以进行聊天,如果逃跑,聊天则结束;
找棋友
private void Discovery_DataThreadCallback((string name, string data) obj)
{
if (Pairung(obj.name, out (PlayerInfo? self, PlayerInfo? rival) pairung, out string msg))
{
string userSelfString = JsonSerializer.Serialize<PlayerInfo>(pairung.self);
string userRivalString = JsonSerializer.Serialize<PlayerInfo>(pairung.rival);
//发送对手信息
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Discovery, Data = new object[] { obj.name, $"{userSelfString}&{userRivalString}" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, "匹配成功!" } });
//发送对手信息
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Discovery, Data = new object[] { pairung.rival?.Name, $"{userRivalString}&{userSelfString}" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { pairung.rival?.Name, "匹配成功!" } });
}
else
{
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, msg } });
}
}
/// <summary>
/// 配对
/// </summary>
/// <param name="name"></param>
/// <param name="msg"></param>
/// <returns></returns>
public bool Pairung(string name, out (PlayerInfo? user_self, PlayerInfo? user_rival) _pairung, out string msg)
{
msg = string.Empty;
_pairung = (null, null);
//过滤自己
List<string> clientNames = TcpServerManager.Instance.GetClientNameList().Where(s => s != name).ToList();
if (clientNames.Count == 0)
{
msg = $"{Model.DataHeaderInfo.Message}无对手,您已无敌,对手都被吓跑了!";
return false;
}
//判断是否已配对
var pairungList = DataManager.Instance.GetPairungList();
(PlayerInfo? user1, PlayerInfo? user2)? this_user = pairungList.FirstOrDefault(q => q.user1?.Name == name || q.user2?.Name == name);
if (this_user is not null && this_user?.user1 is not null && this_user?.user2 is not null)
{
msg = $"{Model.DataHeaderInfo.Message}您已找到合适的棋友, 可以开始下棋了!";
return false;
}
//寻找空闲的棋友
List<string> clientFree = new();
//过滤已配对的棋友
foreach (var item in clientNames)
{
(PlayerInfo? name1, PlayerInfo? name2)? _user = pairungList.FirstOrDefault(q => q.user1?.Name == item || q.user2?.Name == item);
if (_user is not null && _user?.name1 is not null && _user?.name2 is not null) continue;
clientFree.Add(item);
}
if (clientFree.Count == 0)
{
msg = $"{Model.DataHeaderInfo.Message}无棋友!";
return false;
}
int rivalIndex = random.Next(0, clientFree.Count);
var clientRival = clientFree[rivalIndex];
(PlayerInfo? userSelf, PlayerInfo? userRival) pairung = (new PlayerInfo(), new PlayerInfo());
(pairung.userSelf.Name, pairung.userRival.Name) = (name, clientRival);
(pairung.userSelf.State, pairung.userRival.State) = (PlayerState.Prepare, PlayerState.Prepare);
int campIndex = random.Next(0, 2);
ChessCardCamp camp = (ChessCardCamp)campIndex;
(pairung.userSelf.Camp, pairung.userRival.Camp) = (camp, camp == ChessCardCamp.BlackCamp ? ChessCardCamp.WhiteCamp : ChessCardCamp.BlackCamp);
if (pairung.userSelf.Camp == ChessCardCamp.BlackCamp)
pairung.userSelf.CurrCamp = ChessCardCamp.BlackCamp;
else
pairung.userRival.CurrCamp = ChessCardCamp.BlackCamp;
_pairung = pairung;
pairungList.Add(pairung);
return true;
}
重新开始
private void DataNoneParse_DataThreadCallback((string name, string data) obj)
{
if (ReStart(obj.name, out (PlayerInfo? self, PlayerInfo? rival) pairung, out string msg))
{
pairung.self.State = PlayerState.Prepare;
pairung.self.Camp = pairung.self.Camp == ChessCardCamp.BlackCamp ? ChessCardCamp.WhiteCamp : ChessCardCamp.BlackCamp;
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Reset, Data = new object[] { obj.name, "" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, "您已准备! 等待对方重新开始!" } });
pairung.self.Camp = pairung.self.Camp == ChessCardCamp.BlackCamp ? ChessCardCamp.WhiteCamp : ChessCardCamp.BlackCamp;
if (pairung.rival.State == PlayerState.Prepare)
{
pairung.self.CurrCamp = pairung.rival.CurrCamp = ChessCardCamp.BlackCamp;
if (pairung.self.Camp == ChessCardCamp.BlackCamp)
{
pairung.self.Camp = ChessCardCamp.WhiteCamp;
pairung.rival.Camp = ChessCardCamp.BlackCamp;
}
else
{
pairung.self.Camp = ChessCardCamp.BlackCamp;
pairung.rival.Camp = ChessCardCamp.WhiteCamp;
}
string selfString = JsonSerializer.Serialize<PlayerInfo>(pairung.self);
string rivalString = JsonSerializer.Serialize<PlayerInfo>(pairung.rival);
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Reset, Data = new object[] { obj.name, selfString } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Reset, Data = new object[] { pairung.rival.Name, rivalString } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, "开始!" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { pairung.rival.Name, "开始!" } });
}
}
else
{
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, msg } });
}
}
private bool ReStart(string name, out (PlayerInfo? self, PlayerInfo? rival) result, out string msg)
{
result = (null, null);
msg = string.Empty;
var pairungList = DataManager.Instance.GetPairungList();
var exists = pairungList.FirstOrDefault(q => q.user1?.Name == name || q.user2?.Name == name);
if (exists.user1 is null || exists.user2 is null)
{
msg = "请先找对手哈!";
return false;
}
var _pairung = pairungList.FirstOrDefault(q => q.user2?.Name == name);
if (_pairung.user1 is not null && _pairung.user2 is not null)
result = (_pairung.user2, _pairung.user1);
else
result = exists;
if (result.self.State != PlayerState.Free)
{
msg = "无法重新开始, 已准备或已经开始了!";
return false;
}
return true;
}
悔棋
private void RevocationParse_DataThreadCallback((string name, string data) obj)
{
//命令协议----data 1:请求,发起 2: 询问对方 3:对方返回结果 true: 撤回 false:不撤回 4: 结果应答 true: 撤回 false:不撤回
if (string.IsNullOrEmpty(obj.data)) return;
if (Revocation(obj.name, out (PlayerInfo? self, PlayerInfo? rival) pairung, out string msg))
{
string code = obj.data[..1];
string rivalName = pairung.rival?.Name ?? "";
switch (code)
{
case "1":
if (pairung.self.CurrCamp != pairung.self.Camp)
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Revocation, Data = new object[] { rivalName, "2" } });
else
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, "你不能悔棋!" } });
break;
case "3":
string result = obj.data[1..];
if (bool.TryParse(result, out bool isOk))
{
if (isOk) pairung.rival.CurrCamp = pairung.self.CurrCamp = pairung.self.CurrCamp == ChessCardCamp.BlackCamp ? ChessCardCamp.WhiteCamp : ChessCardCamp.BlackCamp;
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Revocation, Data = new object[] { rivalName, $"4{result}" } });
}
break;
}
}
else
{
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, msg } });
}
}
private bool Revocation(string name, out (PlayerInfo? self, PlayerInfo? rival) result, out string msg)
{
result = (null, null);
msg = string.Empty;
var pairungList = DataManager.Instance.GetPairungList();
var exists = pairungList.FirstOrDefault(q => q.user1?.Name == name || q.user2?.Name == name);
if (exists.user1 is null || exists.user2 is null)
{
msg = "请先找对手哈!";
return false;
}
var _pairung = pairungList.FirstOrDefault(q => q.user2?.Name == name);
if (_pairung.user1 is not null && _pairung.user2 is not null)
result = (_pairung.user2, _pairung.user1);
else
result = exists;
if (result.self?.State == PlayerState.Free || result.rival?.State == PlayerState.Free)
{
msg = "您还没有开始呢!";
return false;
}
if (result.self?.State == PlayerState.Prepare || result.rival?.State == PlayerState.Prepare)
{
msg = "刚刚准备好,你悔哪门子的棋!";
return false;
}
//if (result.self?.CurrCamp == result.self?.Camp)
//{
// msg = "你不能撤销!";
// return false;
//}
return true;
}
认输
private void GiveupParse_DataThreadCallback((string name, string data) obj)
{
//命令协议----data 1:请求,发起 2: 询问对方 3:对方返回结果 true: 同意 false:不同意 4: 结果应答 true: 同意 false:不同意
if (string.IsNullOrEmpty(obj.data)) return;
if (Giveup(obj.name, out (PlayerInfo? self, PlayerInfo? rival) pairung, out string msg))
{
string code = obj.data[..1];
string rivalName = pairung.rival?.Name ?? "";
switch (code)
{
case "1":
//if (pairung.self.CurrCamp != pairung.self.Camp)
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Giveup, Data = new object[] { rivalName, "2" } });
//else
//Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, "你不能悔棋!" } });
break;
case "3":
string result = obj.data[1..];
if (bool.TryParse(result, out bool isOk))
{
if (isOk)
{
(pairung.self.State, pairung.rival.State) = (PlayerState.Free, PlayerState.Free);
//Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Giveup, Data = new object[] { rivalName, $"4{result}" } });
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { obj.name, $"对方已认输!" } });
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { rivalName, $"对方同意你认输!" } });
}
else
{
Global.Instance.EventManager.Publish(new EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { rivalName, $"对方不同意你认输!" } });
}
}
break;
}
}
else
{
Global.Instance.EventManager.Publish(new EventServerDataResult()
{
DataHeader = DataHeaderInfo.Message,
Data = new object[] { obj.name, msg }
});
}
}
private bool Giveup(string name, out (PlayerInfo? self, PlayerInfo? rival) result, out string msg)
{
result = (null, null);
msg = string.Empty;
var pairungList = DataManager.Instance.GetPairungList();
var exists = pairungList.FirstOrDefault(q => q.user1?.Name == name || q.user2?.Name == name);
if (exists.user1 is null || exists.user2 is null)
{
msg = "请先找对手哈!";
return false;
}
var _pairung = pairungList.FirstOrDefault(q => q.user2?.Name == name);
if (_pairung.user1 is not null && _pairung.user2 is not null)
result = (_pairung.user2, _pairung.user1);
else
result = exists;
if (result.self.State == PlayerState.Free || result.rival.State == PlayerState.Free)
{
msg = "还没有开始!";
return false;
}
if (result.self.State == PlayerState.Prepare || result.rival.State == PlayerState.Prepare)
{
msg = "刚开始, 认什么输, 相信自己!";
return false;
}
return true;
}
逃跑
private void RunawayParse_DataThreadCallback((string name, string data) obj)
{
if (Runaway(obj.name, out (PlayerInfo? self, PlayerInfo? rival) result, out string msg))
{
string rivalName = result.rival?.Name ?? "";
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Message, Data = new object[] { rivalName, $"你的对手逃跑了!" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Runaway, Data = new object[] { rivalName, $"" } });
Global.Instance.EventManager.Publish(new Model.EventParam.EventServerDataResult() { DataHeader = DataHeaderInfo.Runaway, Data = new object[] { obj.name, $"" } });
}
else
{
Global.Instance.EventManager.Publish(new EventServerDataResult()
{
DataHeader = DataHeaderInfo.Message,
Data = new object[] { obj.name, msg }
});
}
}
private bool Runaway(string name, out (PlayerInfo? self, PlayerInfo? rival) result, out string msg)
{
result = (null, null);
msg = string.Empty;
var pairungList = DataManager.Instance.GetPairungList();
var exists = pairungList.FirstOrDefault(q => q.user1?.Name == name || q.user2?.Name == name);
if (exists.user1 is null || exists.user2 is null)
{
msg = "请先找对手哈!";
return false;
}
var _pairung = pairungList.FirstOrDefault(q => q.user2?.Name == name);
if (_pairung.user1 is not null && _pairung.user2 is not null)
result = (_pairung.user2, _pairung.user1);
else
result = exists;
pairungList.Remove(exists);
return true;
}