-module(game_manager).
|
|
-behaviour(gen_server).
|
|
-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
|
-export([start_game/3, handle_play/2, end_game/1, create_ai_game/0]).
|
|
|
|
-include("../include/game_records.hrl").
|
|
|
|
%% API
|
|
start_link() ->
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
|
|
|
%% 创建一个全AI玩家的游戏
|
|
create_ai_game() ->
|
|
gen_server:call(?MODULE, create_ai_game).
|
|
|
|
% 使用include文件中定义的game_manager_state记录
|
|
|
|
start_game(Player1, Player2, Player3) ->
|
|
% 初始化游戏状态
|
|
GameState = game_core:init_game_state(),
|
|
|
|
% 初始化AI玩家
|
|
AIPlayers = initialize_ai_players(),
|
|
|
|
% 创建游戏管理器状态
|
|
GameManagerState = #game_manager_state{
|
|
game_id = generate_game_id(),
|
|
players = [Player1, Player2, Player3],
|
|
ai_players = AIPlayers,
|
|
current_state = GameState,
|
|
history = []
|
|
},
|
|
|
|
% 开始游戏循环
|
|
game_loop(GameManagerState).
|
|
|
|
handle_play(GameManagerState, Play) ->
|
|
% 验证玩家行动
|
|
case game_core:validate_play(GameManagerState#game_manager_state.current_state, Play) of
|
|
true ->
|
|
% 更新游戏状态
|
|
NewState = game_core:update_state(GameManagerState#game_manager_state.current_state, Play),
|
|
|
|
% 更新AI玩家
|
|
UpdatedAIPlayers = update_ai_players(GameManagerState#game_manager_state.ai_players, Play),
|
|
|
|
% 记录历史
|
|
NewHistory = [Play | GameManagerState#game_manager_state.history],
|
|
|
|
GameManagerState#game_manager_state{
|
|
current_state = NewState,
|
|
ai_players = UpdatedAIPlayers,
|
|
history = NewHistory
|
|
};
|
|
false ->
|
|
{error, invalid_play}
|
|
end.
|
|
|
|
%% 结束游戏
|
|
end_game(GameManagerState) ->
|
|
% 计算最终得分
|
|
FinalScores = calculate_final_scores(GameManagerState),
|
|
|
|
% 更新玩家统计数据
|
|
update_player_stats(GameManagerState, FinalScores),
|
|
|
|
% 保存游戏记录
|
|
save_game_record(GameManagerState),
|
|
|
|
% 返回游戏结果
|
|
{game_ended, FinalScores}.
|
|
|
|
%% 初始化AI玩家
|
|
initialize_ai_players() ->
|
|
% 创建不同类型的AI玩家
|
|
BasicAI = ai_player:init(basic),
|
|
AdvancedAI = advanced_ai_player:init(advanced),
|
|
|
|
% 返回AI玩家列表
|
|
[BasicAI, AdvancedAI].
|
|
|
|
%% 生成游戏ID
|
|
generate_game_id() ->
|
|
% 使用时间戳和随机数生成唯一ID
|
|
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(),
|
|
Random = rand:uniform(1000),
|
|
list_to_binary(io_lib:format("~4..0B~2..0B~2..0B~2..0B~2..0B~2..0B~4..0B",
|
|
[Year, Month, Day, Hour, Minute, Second, Random])).
|
|
|
|
%% 游戏循环
|
|
game_loop(GameManagerState) ->
|
|
% 检查游戏是否结束
|
|
case is_game_over(GameManagerState#game_manager_state.current_state) of
|
|
true ->
|
|
% 游戏结束,返回结果
|
|
end_game(GameManagerState);
|
|
false ->
|
|
% 获取当前玩家
|
|
CurrentPlayer = get_current_player(GameManagerState),
|
|
|
|
% 如果是AI玩家,自动出牌
|
|
case is_ai_player(CurrentPlayer, GameManagerState) of
|
|
true ->
|
|
AIPlay = get_ai_play(CurrentPlayer, GameManagerState),
|
|
NewState = handle_play(GameManagerState, AIPlay),
|
|
game_loop(NewState);
|
|
false ->
|
|
% 如果是人类玩家,返回当前状态等待输入
|
|
{waiting_for_player, GameManagerState}
|
|
end
|
|
end.
|
|
|
|
%% 更新AI玩家
|
|
update_ai_players(AIPlayers, Play) ->
|
|
% 为每个AI玩家更新游戏信息
|
|
lists:map(
|
|
fun(AIPlayer) ->
|
|
update_ai_knowledge(AIPlayer, Play)
|
|
end,
|
|
AIPlayers
|
|
).
|
|
|
|
%% 辅助函数
|
|
|
|
%% 计算最终得分
|
|
calculate_final_scores(GameManagerState) ->
|
|
% 根据游戏规则计算得分
|
|
% 简单实现,实际应该有更复杂的计分逻辑
|
|
Winner = get_winner(GameManagerState),
|
|
Scores = get_player_scores(GameManagerState),
|
|
#{
|
|
winner => Winner,
|
|
scores => Scores
|
|
}.
|
|
|
|
%% 获取获胜者
|
|
get_winner(GameManagerState) ->
|
|
% 简单实现:找出牌已出完的玩家
|
|
GameState = GameManagerState#game_manager_state.current_state,
|
|
Players = GameState#game_state.players,
|
|
case lists:keyfind(0, 2, Players) of
|
|
{Pid, _, _} -> Pid;
|
|
false -> none
|
|
end.
|
|
|
|
%% 获取玩家得分
|
|
get_player_scores(GameManagerState) ->
|
|
% 简单实现:为每个玩家分配基础分数
|
|
GameState = GameManagerState#game_manager_state.current_state,
|
|
Players = GameState#game_state.players,
|
|
lists:foldl(
|
|
fun({Pid, Cards, Role}, Acc) ->
|
|
Score = case Role of
|
|
landlord -> 100 - length(Cards) * 10;
|
|
farmer -> 50 - length(Cards) * 5
|
|
end,
|
|
Acc#{Pid => Score}
|
|
end,
|
|
#{},
|
|
Players
|
|
).
|
|
|
|
%% 更新玩家统计数据
|
|
update_player_stats(GameManagerState, FinalScores) ->
|
|
% 更新玩家的胜率、得分等统计信息
|
|
% 简单实现
|
|
ok.
|
|
|
|
%% 保存游戏记录
|
|
save_game_record(GameManagerState) ->
|
|
% 将游戏记录保存到数据库或文件
|
|
% 简单实现
|
|
ok.
|
|
|
|
%% 检查游戏是否结束
|
|
is_game_over(GameState) ->
|
|
% 检查是否有玩家的牌已经出完
|
|
% 简单实现
|
|
false.
|
|
|
|
%% 获取当前玩家
|
|
get_current_player(GameManagerState) ->
|
|
% 从游戏状态中获取当前玩家
|
|
GameState = GameManagerState#game_manager_state.current_state,
|
|
GameState#game_state.current_player.
|
|
|
|
%% 判断是否为AI玩家
|
|
is_ai_player(Player, GameManagerState) ->
|
|
% 检查玩家是否在AI玩家列表中
|
|
lists:member(Player, GameManagerState#game_manager_state.ai_players).
|
|
|
|
%% 获取AI出牌
|
|
get_ai_play(AIPlayer, GameManagerState) ->
|
|
% 调用AI模块获取出牌决策
|
|
GameState = GameManagerState#game_manager_state.current_state,
|
|
ai_core:make_decision(AIPlayer, GameState).
|
|
|
|
%% 更新AI知识
|
|
update_ai_knowledge(AIPlayer, Play) ->
|
|
% 更新AI对游戏的认知
|
|
ai_core:update_knowledge(AIPlayer, Play).
|
|
|
|
%% Callbacks
|
|
init([]) ->
|
|
% 初始化状态
|
|
{ok, #{active_games => #{}, game_count => 0}}.
|
|
|
|
handle_call(create_ai_game, _From, State = #{active_games := Games, game_count := Count}) ->
|
|
% 创建三个AI玩家
|
|
{ok, AI1} = ai_player:create_ai_player(normal),
|
|
{ok, AI2} = ai_player:create_ai_player(normal),
|
|
{ok, AI3} = ai_player:create_ai_player(hard),
|
|
|
|
% 启动游戏
|
|
GameState = start_game(AI1, AI2, AI3),
|
|
GameId = Count + 1,
|
|
|
|
% 更新状态
|
|
NewGames = maps:put(GameId, GameState, Games),
|
|
|
|
% 启动自动游戏进程
|
|
spawn(fun() -> auto_game_loop(GameId, GameState) end),
|
|
|
|
{reply, {ok, GameId}, State#{active_games => NewGames, game_count => GameId}};
|
|
|
|
handle_call(_Request, _From, State) ->
|
|
{reply, {error, unknown_call}, State}.
|
|
|
|
handle_cast(_Msg, State) ->
|
|
{noreply, State}.
|
|
|
|
handle_info(_Info, State) ->
|
|
{noreply, State}.
|
|
|
|
terminate(_Reason, _State) ->
|
|
ok.
|
|
|
|
code_change(_OldVsn, State, _Extra) ->
|
|
{ok, State}.
|
|
|
|
%% 自动游戏循环
|
|
auto_game_loop(GameId, GameState) ->
|
|
% 检查游戏是否结束
|
|
case is_game_over(GameState#game_manager_state.current_state) of
|
|
true ->
|
|
% 游戏结束,记录结果
|
|
end_game(GameState);
|
|
false ->
|
|
% 获取当前玩家
|
|
CurrentPlayer = get_current_player(GameState),
|
|
|
|
% AI自动出牌
|
|
AIPlay = get_ai_play(CurrentPlayer, GameState),
|
|
NewState = handle_play(GameState, AIPlay),
|
|
|
|
% 添加延迟使游戏更自然
|
|
timer:sleep(500),
|
|
|
|
% 继续游戏循环
|
|
auto_game_loop(GameId, NewState)
|
|
end.
|