Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>disable</Nullable>
|
||||
<AssemblyName>RPS.Core</AssemblyName>
|
||||
<RootNamespace>RPS.Core</RootNamespace>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Core 唯一源码位:客户端 scripts~/Core('~' 目录 Unity 不编译;服务端/客户端两端共用同一批 .cs) -->
|
||||
<Compile Include="..\..\..\..\Client\Assets\MiniGames\RockPaperScissors\scripts~\Core\**\*.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Framework.Shared\Framework.Shared.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>disable</Nullable>
|
||||
<AssemblyName>RPS.Server</AssemblyName>
|
||||
<RootNamespace>RPS.Server</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Framework.Shared\Framework.Shared.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\RPS.Core\RPS.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using XWorld.Framework;
|
||||
using XWorld.Framework.Protocol;
|
||||
using RPS.Core;
|
||||
|
||||
namespace RPS.Server
|
||||
{
|
||||
public sealed class RpsServerRoom : IGameServerRoom
|
||||
{
|
||||
public const ushort SnapshotOpcode = 1;
|
||||
public const ushort ChoiceOpcode = 1; // 客户端出招消息 opcode
|
||||
|
||||
private readonly RpsLogic _logic = new RpsLogic();
|
||||
private IRoomCtx _ctx;
|
||||
private RpsState _state;
|
||||
private readonly Dictionary<int, int> _seatOf = new Dictionary<int, int>(); // playerId->seat
|
||||
private readonly int[] _pidOfSeat = new int[2]; // seat->playerId(结算用;AI 也有 pid)
|
||||
private bool _ended;
|
||||
|
||||
public void OnRoomStart(IReadOnlyList<PlayerInfo> players, IRoomCtx ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
_state = _logic.CreateInitial(new RoomConfig { GameId = "rps", Version = 1, Seed = 1, PlayerCount = players.Count }, ctx.Random);
|
||||
for (int i = 0; i < players.Count && i < 2; i++)
|
||||
{
|
||||
_seatOf[players[i].PlayerId] = i;
|
||||
_pidOfSeat[i] = players[i].PlayerId;
|
||||
_state.IsAi[i] = players[i].IsAI;
|
||||
}
|
||||
Broadcast();
|
||||
}
|
||||
|
||||
public void OnMessage(int playerId, NetMessage message)
|
||||
{
|
||||
if (message.Opcode != ChoiceOpcode) return;
|
||||
if (!_seatOf.TryGetValue(playerId, out int seat)) return;
|
||||
var r = new PacketReader(message.Payload);
|
||||
var choice = (Choice)r.ReadByte();
|
||||
_state = _logic.Step(_state, RpsInput.Choose(seat, choice), _ctx.Random).State;
|
||||
}
|
||||
|
||||
public void OnTick(float dt)
|
||||
{
|
||||
if (_ended) return;
|
||||
// Choosing 阶段:AI 座位等概率出招(不读对手),仅在尚未出招时
|
||||
if (_state.Phase == RpsPhase.Choosing)
|
||||
for (int seat = 0; seat < 2; seat++)
|
||||
if (_state.IsAi[seat] && _state.Choices[seat] == Choice.None)
|
||||
{
|
||||
var c = new[] { Choice.Rock, Choice.Paper, Choice.Scissors }[_ctx.Random.Next(3)];
|
||||
_state = _logic.Step(_state, RpsInput.Choose(seat, c), _ctx.Random).State;
|
||||
}
|
||||
|
||||
var res = _logic.Step(_state, RpsInput.Tick(dt), _ctx.Random);
|
||||
_state = res.State;
|
||||
Broadcast();
|
||||
|
||||
if (_state.Phase == RpsPhase.Finished)
|
||||
{
|
||||
_ended = true;
|
||||
int s0 = _state.Scores[0], s1 = _state.Scores[1];
|
||||
bool draw = _state.Winner == 2;
|
||||
_ctx.Logger.Info($"rps finished, winner seat={_state.Winner}, scores {s0}:{s1}");
|
||||
_ctx.EndRoom(new RoomEndResult
|
||||
{
|
||||
WinnerPlayerId = draw ? 0 : _pidOfSeat[_state.Winner],
|
||||
ResultBlob = Encoding.UTF8.GetBytes(draw ? $"平局 {s0} : {s1}" : $"最终比分 {s0} : {s1}")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRoomEnd() => _ctx.Logger.Info("rps room end");
|
||||
|
||||
private void Broadcast() => _ctx.Broadcast(new NetMessage(SnapshotOpcode, _logic.Encode(_state)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user