Advertisement
simserver

oneCardLight.pl

Sep 8th, 2015
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 17.38 KB | None | 0 0
  1. /* -*- Mode:Prolog -*- */
  2.  
  3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4. % Gameserver-Spielengine fuer ONECARDLIGHT %        
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6.  
  7. :- module(oneCardLight,[initMatch_oneCardLight/8,play_oneCardLight/9,joinMatch_oneCardLight/7]).
  8.  
  9. :- use_module(library(file_systems)).
  10. :- use_module(library(lists)).
  11. :- ensure_loaded(simutils).
  12. :- use_module(remoteaiwrapper).
  13.  
  14. % JavaEinstieg: nachträgliches Beitreten nicht möglich
  15. joinMatch_oneCardLight(_MatchID,_PlayerDetails,_Oldworld,_Newworld,_Views,_Round,_Phase).
  16.  
  17. /*------------------- JavaEinstieg: INITMATCH ---------------------------------------------------------*/
  18. % erstellt Spiel
  19. initMatch_oneCardLight(_MatchID,_MatchOptions,PlayerList,PlayerDetails,Worldout,Views,Round,Phase) :-
  20.         PlayerList = [Player1,Player2],                                         % Player1=player1, Player2=player2
  21.         PlayerDetails = [player(Detail1,_N1,_Role1),player(Detail2,_N2,_Role2)],% D1=human, N1=de, Role1=north, D2=localai(oneCardPlayer), N2=@oneCardPlayer, Role2=south
  22.         PlayerDetailDict = [Player1-Detail1, Player2-Detail2],                  % P1-D1=player1-human, P2-D2=player2-localai(oneCardPlayer)
  23.        
  24.         InitialPlayer1Hand = [7],
  25.         InitialPlayer2Hand = [4],
  26.         InitialTalon = [8,3],
  27.        
  28.         World = [player1-InitialPlayer1Hand,player2-InitialPlayer2Hand,talon-InitialTalon,
  29.                  status-beforeTrick,lead-Player1,winner-nil,
  30.                  playHistory-[],
  31.                  playerDetailDict-PlayerDetailDict,
  32.                  player1KB-[],player2KB-[]],
  33.        
  34.         playersworld(Player1,World,Player1world),                               % erstellt Spielerwelt
  35.         playersworld(Player2,World,Player2world),
  36.         playersviewWithoutActions(Player1world,Player1view1),                   % erstellt Spielerview ohne Aktionen
  37.         playersviewWithoutActions(Player2world,Player2view1),
  38.         playersviewWithAllowedActions(Player1world,Player1view1,Player1view2),  % erweitert Spielerview um Aktionen
  39.         playersviewWithAllowedActions(Player2world,Player2view1,Player2view2),
  40.        
  41.         Worldout = World,
  42.         Views = [Player1view2,Player2view2],
  43.         Round = '1',
  44.         Phase = 'default',
  45.         true.
  46.  
  47.  
  48. % beschreibt die Welt eines bestimmten Spielers
  49. playersworld(Player,World,PlayersWorld) :-
  50.         worldget(Player,World,PlayersHand),
  51.         worldget(talon,World,Talon),
  52.         length(Talon,TalonCount),
  53.         worldget(status,World,Status),
  54.         worldget(lead,World,Lead),
  55.         worldget(winner,World,Winner),
  56.         worldget(playHistory,World,PlayHistory),
  57.        
  58.         PlayersWorld = [playersName-Player,
  59.                         playersHand-PlayersHand,talonCount-TalonCount,
  60.                         status-Status,lead-Lead, winner-Winner,
  61.                         playHistory-PlayHistory],
  62.         true.
  63.  
  64. % wandelt die Welt eines Spielers in Views um
  65. playersviewWithoutActions(PlayersWorld,PlayersView) :-
  66.         worldget(playersName,PlayersWorld,Player),
  67.         worldget(lead,PlayersWorld,Lead),
  68.         worldget(playersHand,PlayersWorld,OwnHand),
  69.         worldget(talonCount,PlayersWorld,TalonCount),
  70.         worldget(playHistory,PlayersWorld,PlayHistory),
  71.         worldget(status,PlayersWorld,Status),
  72.    
  73.         length(OwnHand,OwnHandCount),                           % # eigene Handkarten
  74.         (Status = inTrick ->    % eine Karte wurde gespielt     % # gegnerische Handkarten
  75.          (Lead = Player ->      % ich bin dran
  76.           OpponentHandCount is 2 - TalonCount
  77.          ;                      % ich bin nicht dran
  78.           OpponentHandCount = 1
  79.          )
  80.         ;
  81.          (Status = beforeTrick -> % keine Karte wurde gespielt
  82.           OpponentHandCount = 1
  83.          ;
  84.           (Status = end ->
  85.            OpponentHandCount is 2 - TalonCount - OwnHandCount
  86.           ;
  87.            throw(unknownStatus-Status)
  88.           )
  89.          )
  90.         ),
  91.          
  92.         (Status = inTrick ->                                    % bestimmt Karten für die Stichpositionen
  93.          PlayHistory = [FirstTrickCard|_],
  94.          CurrentTrick = [FirstTrickCard]
  95.         ;
  96.          (PlayHistory = [SecondTrickCard,FirstTrickCard|_] ->
  97.           CurrentTrick = [FirstTrickCard,SecondTrickCard]
  98.          ;
  99.           CurrentTrick = []
  100.          )
  101.         ),
  102.        
  103.         ViewCards0 = [],
  104.         putVisibleCards(OwnHand,ViewCards0,ViewCards1,1),               % eigene Handkarten auf den View
  105.         putHiddenCards(TalonCount,ViewCards1,ViewCards2,3),             % Stapel auf den View
  106.         putHiddenCards(OpponentHandCount,ViewCards2,ViewCards3,2),      % gegnerische Handkarten auf den View
  107.         putVisibleCards(CurrentTrick,ViewCards3,ViewCards4,5),          % aktuellen Stich auf den View
  108.         putMissingCards(ViewCards4,ViewCards),                         % alle übrigen Positionen werden mit "none-0" belegt
  109.        
  110.         (Status = end ->
  111.          worldget(winner,PlayersWorld,Winner),
  112.          atom_concat('Winner: ',Winner,WinnerText),
  113.          Message = WinnerText
  114.         ;
  115.          Message = 'inGame'
  116.         ),
  117.        
  118.         Form = [form(1,[text(Message)])],
  119.                
  120.         PlayersView = view(Player,ViewCards,[],[],Form,[],undo(0,[]),[]),
  121.         true.
  122.  
  123. % Legt für den Spieler sichtbare Karten auf den View.
  124. putVisibleCards([],View,View,_Position).
  125. putVisibleCards([Card|RestCards],ViewIn,ViewOut,Position) :-
  126.         number_card(Card,CardName),
  127.         NextPosition is Position + 1,
  128.         NextView = [Position-card(CardName)|ViewIn],
  129.         putVisibleCards(RestCards,NextView,ViewOut,NextPosition).
  130.  
  131. % Legt für den Spieler verdeckte Karten auf den View.
  132. putHiddenCards(0,View,View,_Position).
  133. putHiddenCards(Count,ViewIn,ViewOut,Position) :-
  134.         Count > 0,
  135.         NextCount is Count - 1,
  136.         NextPosition is Position + 1,
  137.         NextView = [Position-card(hiddenCard)|ViewIn],
  138.         putHiddenCards(NextCount,NextView,ViewOut,NextPosition).
  139.  
  140. % Fuegt an allen Positionen fuer die keine Karte bekannt ist explizit "none-0" ein.
  141. putMissingCards(ViewIn,ViewOut) :-
  142.         range(1,6,AllPositions), % AllPositions=[1,2,...,6]
  143.         putMissingCards(ViewIn,ViewOut,AllPositions).
  144. putMissingCards(View,View,[]).
  145. putMissingCards(ViewIn,ViewOut,[Position|RestPositions]) :-
  146.         member(Position-_,ViewIn),
  147.         !,
  148.         putMissingCards(ViewIn,ViewOut,RestPositions).
  149. putMissingCards(ViewIn,ViewOut,[Position|RestPositions]) :-
  150.         NextView = [Position-card(none-0)|ViewIn],
  151.         putMissingCards(NextView,ViewOut,RestPositions).
  152.  
  153. % Zuordnung von Zehnerkarten zu frz. Kartenspiel
  154. number_card(0,h-a):-!.
  155. number_card(1,h-2):-!.
  156. number_card(2,h-3):-!.
  157. number_card(3,h-4):-!.
  158. number_card(4,h-5):-!.
  159. number_card(5,h-6):-!.
  160. number_card(6,h-7):-!.
  161. number_card(7,h-8):-!.
  162. number_card(8,h-9):-!.
  163. number_card(9,h-t):-!.
  164. number_card(talon,hiddenCard):-!.
  165. number_card(N,C) :- throw(numbercard_conversion_error(N,C)).
  166.  
  167. % erweitert die PlayerView um Aktionen
  168. playersviewWithAllowedActions(PlayersWorld,PlayersViewIn,PlayersViewOut) :-
  169.         PlayersViewIn = view(Player,ViewCards,PlayerAnimations,_,Form,Magic,Undo,Chat),
  170.         worldget(lead,PlayersWorld,Lead),
  171.        
  172.         (dif(Player,Lead) ->    % Spieler nicht dran
  173.          PlayerAllowedActions = []
  174.         ;                       % Spieler dran
  175.          PlayerAllowedActions1 = [1-[click]],                           % Handkarte        
  176.          worldget(talonCount,PlayersWorld,TalonCount),
  177.          worldget(TalonCount,[1-3,2-4],Position),
  178.          PlayerAllowedActions = [Position-[click]|PlayerAllowedActions1]% Stapelkarte
  179.         ),
  180.        
  181.         PlayersViewOut = view(Player,ViewCards,PlayerAnimations,PlayerAllowedActions,Form,Magic,Undo,Chat),
  182.         true.
  183.  
  184. /*------------------- JavaEinstieg: PLAY ---------------------------------------------------------*/
  185. % führt Spielzug aus
  186. play_oneCardLight(Player,GuiactionIn,_MatchNumber,WorldIn,WorldOut,Views,Matchstate,Round,Phase) :-
  187.         (isGuiPlayer(WorldIn,Player) -> % prüft ob Mensch oder AI
  188.          guiActionHandler(WorldIn,GuiactionIn,Gameaction), % GUI-Action verarbeiten
  189.          Guiaction = GuiactionIn,
  190.          PlayerKB = []
  191.         ;
  192.          aiActionHandler(WorldIn,GuiactionAi,Gameaction,PlayerKB), % AI-Action holen
  193.          Guiaction = GuiactionAi
  194.         ),
  195.        
  196.         % KnowledgeBase in der Welt aktualisieren (für KI-Spieler)
  197.         atom_concat(Player,'KB',PlayerKBkey),
  198.         worldput(PlayerKBkey,WorldIn,PlayerKB,World0),
  199.        
  200.         % Gameaction in der Welt ausführen
  201.         actionToWorld(Gameaction,World0,World),
  202.        
  203.         % Matchstate definieren
  204.         worldget(status,World,Status),
  205.         (Status = end ->
  206.          worldget(winner,World,Winner),
  207.          (Winner = player1 ->
  208.           Loser = player2
  209.          ;
  210.           Loser = player1
  211.          ),
  212.          debprintln('GAME OVER',3),
  213.          Matchstate0 = matchstate(finished,[player(Winner,won,1),player(Loser,lost,0)])
  214.         ;
  215.          Matchstate0 = matchstate(running(0),[])
  216.         ),
  217.        
  218.         % Dynamischen Views der Spieler erstellen
  219.         dynamicview(player1,Gameaction,Guiaction,WorldIn,World,View1),
  220.         dynamicview(player2,Gameaction,Guiaction,WorldIn,World,View2),
  221.        
  222.         % Dynamischen Views die erlaubten Aktionen hinzufügen
  223.         playersworld(player1,World,Player1World),
  224.         playersworld(player2,World,Player2World),
  225.         playersviewWithAllowedActions(Player1World,View1,View12),
  226.         playersviewWithAllowedActions(Player2World,View2,View22),
  227.        
  228.         % Output:
  229.         WorldOut = World,
  230.         Views = [View12,View22],
  231.         Matchstate = Matchstate0,
  232.         Round = '1',
  233.         Phase = 'default',
  234.         true.
  235.  
  236. % true wenn menschlicher Spieler
  237. isGuiPlayer(World,Player) :-
  238.         worldget(playerDetailDict,World,PlayerDetailDict),
  239.         worldget(Player,PlayerDetailDict,Type),
  240.         Type = human.
  241.  
  242. % behandelt alle GUI-Ereignisse
  243. guiActionHandler(World,Guiaction,Gameaction) :-
  244.         worldget(lead,World,Player),
  245.         playersworld(Player,World,Playersworld),
  246.         playersviewWithoutActions(Playersworld,view(_,ViewCards,_,_,_,_,_,_)),
  247.         guiactionToGameaction(Guiaction,ViewCards,Gameaction),
  248.         true.
  249.  
  250. % Wandelt eine GUI-Action in eine Game-Action um.
  251. guiactionToGameaction(click(Position),ViewCards,play(Number)) :-
  252.         worldget(Position,ViewCards,card(CardName)),
  253.         number_card(Number,CardName),
  254.         true.
  255.  
  256. % Behandelt analog zum Guiactionhandler KI-Aktionen.
  257. aiActionHandler(World,Guiaction,Gameaction,NewKB) :-
  258.         worldget(lead,World,Player),
  259.         playersworld(Player,World,Playersworld),
  260.         playersviewWithoutActions(Playersworld,view(_,ViewCards,_,_,_,_,_,_)),
  261.        
  262.         worldget(playerDetailDict,World,PlayerDetailDict),
  263.         worldget(Player,PlayerDetailDict,PlayerDetails),
  264.         atom_concat(Player,'KB',PlayerKBkey),
  265.         worldget(PlayerKBkey,World,OldKB),
  266.        
  267.         (PlayerDetails = localai(AiName) ->
  268.          aifolder(Aifolder), % Ordner, in dem die AI-Spieler liegen (atom, incl. Slash am Ende)
  269.          atom_concat('z_modulename_',AiName,AiModule),
  270.          atoms_concat([Aifolder,AiName,'/z_modulename_',AiName],AiModulePath),
  271.          atoms_concat([Aifolder,AiName,'/'],AiPath),
  272.          current_directory(Serverpath,AiPath), % aktuellen Working Dir merken, aber auf AiPath setzen
  273.          use_module(AiModulePath),
  274.          atom_concat('z_',AiName,AiPredicate),
  275.          AiGoal =.. [AiPredicate,_Version,Playersworld,OldKB,Gameaction,NewKB],
  276.          (AiModule:AiGoal ->
  277.           current_directory(_,Serverpath), % zurueck zum Server-Verzeichnis
  278.           true
  279.          ;
  280.           current_directory(_,Serverpath),% zurueck zum Server-Verzeichnis
  281.           throw(gameException('LocalAiFailed'))
  282.          ),
  283.          true
  284.         ;
  285.          (PlayerDetails = remoteai(Host,Port) ->
  286.           (Port = 3142 ->
  287.            Protocol = socket
  288.           ;
  289.            Protocol = webservice
  290.           )
  291.          ;
  292.           PlayerDetails = remoteai(Host,Port,Protocol)
  293.          ),
  294.          remoteAiHost_port_protocol_playersWorld_oldkb_newkb_action(Host,Port,Protocol,Playersworld,OldKB,NewKB,Gameaction)
  295.         ),
  296.         !,
  297.        
  298.         (Gameaction = play(_) ->
  299.          gameactionToGuiaction(Gameaction,ViewCards,Guiaction) % Was waere die Guiaction hierzu?
  300.         ;
  301.          (Gameaction = timeoutError ->
  302.           throw(gameException('{AITimeOut}'))
  303.          ;
  304.           throw(gameException('{UnImplementedAIAction}'-Gameaction))
  305.          )
  306.         ),
  307.         true.
  308.  
  309. % wandelt eine Game-Action in eine GUI-Action um
  310. gameactionToGuiaction(play(Card),ViewCards,click(Position)) :-
  311.         (dif(Card,talon) ->     % spielt Handkarte
  312.          number_card(Card,CardName),
  313.          worldget(Position,ViewCards,card(CardName))
  314.         ;                       % spielt Stapel
  315.          worldget(4,ViewCards,Talon),
  316.          (Talon = card(hiddenCard) ->
  317.           Position = 4
  318.          ;
  319.           Position = 3
  320.          )
  321.         ),
  322.         true.
  323.  
  324. % führe Gameaction aus
  325. actionToWorld(play(Card),WorldIn,WorldOut) :- % Handkarte wird gespielt
  326.         (dif(Card,talon) ->     % spielt Handkarte
  327.          worldget(lead,WorldIn,Player),
  328.          worldget(Player,WorldIn,Hand),
  329.          select(Card,Hand,RestCards),
  330.          worldput(Player,WorldIn,RestCards,World0),     % gespielte Karte aus Hand entfernen
  331.          PlayCard = Card
  332.         ;                       % spielt Stapelkarte
  333.          worldget(talon,WorldIn,[TalonCard|Talon]),
  334.          worldput(talon,WorldIn,Talon,World0),          % gespielte Karte vom Stapel entfernen
  335.          PlayCard = TalonCard
  336.         ),
  337.         worldget(playHistory,World0,PlayHistory),
  338.         worldput(playHistory,World0,[PlayCard|PlayHistory],World1), % in play history eintragen
  339.                
  340.         trickHandling(World1,WorldOut),
  341.         true.
  342.  
  343. % wertet den Stich aus
  344. trickHandling(WorldIn,WorldOut) :-
  345.         worldget(lead,WorldIn,Player),
  346.         (Player = player1 ->
  347.          Opponent = player2
  348.         ;
  349.          Opponent = player1
  350.         ),
  351.         worldget(status,WorldIn,Status),
  352.        
  353.         (Status = beforeTrick ->        % erste Karte wird ausgespielt
  354.          worldput(lead,WorldIn,Opponent,World1),
  355.          worldput(status,World1,inTrick,World2)
  356.         ;                               % zweite Karte wird ausgespielt
  357.          worldget(playHistory,WorldIn,[Card1,Card2|_]), % Opponent spielte Card2, Player spielt Card1
  358.          (Card1 > Card2 ->
  359.           Winner = Player
  360.          ;
  361.           Winner = Opponent
  362.          ),
  363.          worldput(winner,WorldIn,Winner,World0),
  364.          worldput(lead,World0,nil,World1),
  365.          worldput(status,World1,end,World2)
  366.         ),
  367.        
  368.         WorldOut = World2,
  369.         true.
  370.  
  371. % berechnet alle Animationen, die für den Zug gemacht werden müssen
  372. dynamicview(Player,Gameaction,Guiaction,OldWorld,NewWorld,Dynamicview) :-
  373.         playersworld(Player,OldWorld,OldPlayerWorld),
  374.         playersviewWithoutActions(OldPlayerWorld,view(_,OldPlayerViewCards,_,_,_,_,_,_)),
  375.        
  376.         playersworld(Player,NewWorld,NewPlayerWorld),
  377.         playersviewWithoutActions(NewPlayerWorld,view(_,NewPlayerViewCards,_,_,PlayerForm,Magic,Undo,Chat)),
  378.        
  379.         worldget(lead,OldWorld,Lead),
  380.         moveAnimation(Lead,Player,OldPlayerViewCards,Gameaction,Guiaction,PlayerMoveAnimations),     % animiere den Flug der Karte
  381.         animations(OldPlayerViewCards,NewPlayerViewCards,PlayerAnimations),
  382.         append(PlayerMoveAnimations,PlayerAnimations,AllPlayerAnimations),
  383.        
  384.         DynamicPlayerView = view(Player,OldPlayerViewCards,AllPlayerAnimations,_,PlayerForm,Magic,Undo,Chat), % Dynamic-Views sind Old-Views plus Animation (im Gegensatz zu den theoretischen STATISCHEN NewViews)
  385.        
  386.         Dynamicview = DynamicPlayerView,
  387.         true.
  388.  
  389. % Berechnet die Animation der "fliegenden" Karte.
  390. moveAnimation(Actor,Player,ViewCards,Gameaction,Guiaction,[move(FromPosition,ToPosition,HiddenCard,card(VisibleAs))]) :-
  391.         Guiaction = click(ActorsFromPosition),
  392.         ((Actor = Player;Gameaction = play(talon)) ->
  393.          FromPosition = ActorsFromPosition
  394.         ;
  395.          FromPosition = 2
  396.         ),
  397.         worldget(FromPosition,ViewCards,OldCard), % was wurde an der Stelle, an der die Animation beginnt, zuvor dargestellt?
  398.         (OldCard = card(hiddenCard) ->
  399.          HiddenCard = card(hiddenCard)
  400.         ;
  401.          HiddenCard = card(none-0), % anschliessend rueckt eh die Karte rechts davon nach
  402.          true
  403.         ),
  404.         Gameaction = play(Number),
  405.         number_card(Number,VisibleAs),
  406.              
  407.         (member(5-card(none-0),ViewCards) -> % naechste freie Position fuer Trick-Karte
  408.          ToPosition = 5
  409.         ;
  410.          ToPosition = 6
  411.         ),
  412.         true.
  413.  
  414. % Berechne aus dem Unterschied der ViewCards die darzustellenden Animationen.
  415. animations(_OldViewCards,[],[]).
  416. animations(OldViewCards,[FirstNew|RestNewViewCards],Animations) :-
  417.         member(FirstNew,OldViewCards), % Feld war vorher genauso belegt -> nicht zu animieren
  418.         animations(OldViewCards,RestNewViewCards,Animations).
  419. animations(OldViewCards,[FirstNew|RestNewViewCards],[update(Position,Card)|Animations]) :-        
  420.         FirstNew = Position-Card,
  421.         animations(OldViewCards,RestNewViewCards,Animations).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement