Skip to content
Extraits de code Groupes Projets
Valider 00a07f1e rédigé par Vany Ingenzi's avatar Vany Ingenzi
Parcourir les fichiers

Fully Functional TurnByTurn and RandomPlayer

parent 5de7f09b
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -65,17 +65,17 @@ in
%%%% Players description %%%%
NbPlayers = 2
Players = [player000basic player001basic]
Colors = [black c(245 88 203)]
NbPlayers = 3
Players = [player000basic player001basic player002basic]
Colors = [black c(245 88 203) c(255 102 0)]
%%%% Surface time/turns %%%%
TurnSurface = 3
TurnSurface = 5
%%%% Life %%%%
MaxDamage = 4
MaxDamage = 8
%%%% Number of load for each item %%%%
......
......@@ -35,34 +35,54 @@ define
{List.map Players fun{$ Player} if Player==Current then {F Player} else Player end end}
end
fun {WeHaveAWinner Players Acc}
case Players of nil then Acc==1
[]Player|Others then Resp in
{Send Player.port isDead(Resp)}
if Resp==true then
{WeHaveAWinner Others Acc}
else
{WeHaveAWinner Others Acc+1}
end
end
end
%% NextPlayers : The next players to play
%% CurrentIndex : The index of the next player
%% Indicate Next : Unbound variable for the turn
fun {TurnByTurn1 Players CurrentIndex Next}
proc {TurnByTurn1 Players CurrentIndex}
CurrentPlayer={List.nth Players CurrentIndex}
fun{IncrNbSurface Player} player(port:Player.port nbSurface:Player.nbSurface+1) end
NewPlayers
in
if CurrentPlayer.nbSurface > 0 andthen CurrentPlayer.nbSurface < Input.turnSurface then
Next = 9
{ModifyOnlyCurrent Players CurrentPlayer IncrNbSurface}
if {WeHaveAWinner Players 0} then
skip
else
Next = 2 Players
end
if CurrentPlayer.nbSurface > 0 andthen CurrentPlayer.nbSurface < Input.turnSurface then
NewPlayers={ModifyOnlyCurrent Players CurrentPlayer IncrNbSurface}
{TurnByTurn NewPlayers (CurrentIndex mod Input.nbPlayer)+1}
else
{TurnByTurn2 Players CurrentIndex}
end
end
end
%% NextPlayers : The next players to play
%% CurrentIndex : The index of the next player
fun {TurnByTurn2 Players CurrentIndex}
proc {TurnByTurn2 Players CurrentIndex}
CurrentPlayer={List.nth Players CurrentIndex}
fun{SetNbSurfaceZero Player}
{Send Player.port dive}
player(port:Player.port nbSurface:0)
end
NewPlayers
in
if CurrentPlayer.nbSurface == Input.turnSurface then
{ModifyOnlyCurrent Players CurrentPlayer SetNbSurfaceZero}
NewPlayers={ModifyOnlyCurrent Players CurrentPlayer SetNbSurfaceZero}
{TurnByTurn345 NewPlayers CurrentIndex}
else
Players
NewPlayers=Players
{TurnByTurn345 NewPlayers CurrentIndex}
end
end
......@@ -81,7 +101,7 @@ define
{Send Player.port sayMineExplode(Id Position Resp)}
case Resp of null then skip
[] sayDeath(ID) then
{Send GUI_PORT lifeUpdate(ID 0)}
{Send GUI_PORT removePlayer(ID)}
{Broadcast Players Resp}
[] sayDamageTaken(ID Damage LifeLeft) then
{Send GUI_PORT lifeUpdate(ID LifeLeft)}
......@@ -119,23 +139,26 @@ define
end}
end
fun {TurnByTurn345 Players CurrentIndex Next}
proc {TurnByTurn345 Players CurrentIndex}
CurrentPlayer={List.nth Players CurrentIndex}
ID Pos Direction NewPlayers
fun{SetNbSurfaceOne Player} player(port:Player.port nbSurface:1) end
in
{Send CurrentPlayer.port move(ID Pos Direction)}
case Direction
of surface then
case ID#Direction
of null#_ then
%% 9.
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] _#surface then
%% 9.
NewPlayers={ModifyOnlyCurrent Players CurrentPlayer SetNbSurfaceOne}
{Broadcast NewPlayers saySurface(ID)} {Send GUI_PORT surface(ID)}
Next=9
NewPlayers
{TurnByTurn NewPlayers (CurrentIndex mod Input.nbPlayer)+1}
else
%% 6.
{Broadcast Players sayMove(ID Direction)}
{Send GUI_PORT movePlayer(ID Pos)}
Next=6
Players
{TurnByTurn6 Players CurrentIndex}
end
end
......@@ -144,9 +167,15 @@ define
ID KindItem
in
{Send CurrentPlayer.port chargeItem(ID KindItem)}
case KindItem of null then skip
else
{Broadcast Players sayCharge(ID KindItem)}
case ID#KindItem
of null#_ then
%% 9.
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] _#null then
{TurnByTurn78 Players CurrentIndex}
[] _#ChargedItem then
{Broadcast Players sayCharge(ID ChargedItem)}
{TurnByTurn78 Players CurrentIndex}
end
end
......@@ -155,53 +184,37 @@ define
ID KindFire
in
{Send CurrentPlayer.port fireItem(ID KindFire)}
case KindFire of null then skip
case KindFire of null then
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] mine(Position) then Id Mine in
{Send GUI_PORT putMine(ID Position)} {Broadcast Players sayMinePlaced(ID)}
{Send CurrentPlayer.port fireMine(Id Mine)}
case Mine of null then skip %% To Be Studied
else
{Send GUI_PORT explosion(Id Position)}
{ManageMineExplosion Id Players Position}
case Mine of null then
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] mine(PosMineExploded) then
% {Send GUI_PORT explosion(Id PosMineExploded)}
{Send GUI_PORT removeMine(Id PosMineExploded)}
{ManageMineExplosion Id Players PosMineExploded}
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
end
[] missile(Position) then
{ManageMissileExplosion ID Players Position}
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] drone(U V) then
{Send GUI_PORT drone(ID KindFire)}
{ManagingDroneFiring Players CurrentPlayer KindFire}
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
[] sonar then
{Send GUI_PORT sonar(ID)}
{ManagingSonarFiring Players CurrentPlayer}
{TurnByTurn Players (CurrentIndex mod Input.nbPlayer)+1}
end
end
proc {TurnByTurn Players CurrentIndex}
NewPlayers1 NewPlayers2 NewPlayers3
Next1 Next345
in
% {System.show 'Turnof'#CurrentIndex}
%% 1.
{System.show 'Turnof'#CurrentIndex}
NewPlayers1 = {TurnByTurn1 Players CurrentIndex Next1}
if Next1==2 then
%% 2.
NewPlayers2 = {TurnByTurn2 NewPlayers1 CurrentIndex}
%% 345.
NewPlayers3 = {TurnByTurn345 NewPlayers2 CurrentIndex Next345}
if Next345==6 then
%% 6.
{TurnByTurn6 NewPlayers3 CurrentIndex}
%% 78.
{TurnByTurn78 NewPlayers3 CurrentIndex}
%% 9.
{TurnByTurn NewPlayers3 (CurrentIndex mod Input.nbPlayer)+1}
else
%% 9.
{TurnByTurn NewPlayers1 (CurrentIndex mod Input.nbPlayer)+1}
end
else
%% 9.
{TurnByTurn NewPlayers1 (CurrentIndex mod Input.nbPlayer)+1}
end
{TurnByTurn1 Players CurrentIndex}
end
in
%%1.
......@@ -222,8 +235,8 @@ in
end}
%%4. Launch the game
if Input.isTurnByTurn then
{TurnByTurn PlayersList 1}
end
end
......@@ -46,7 +46,7 @@ define
RandomPt = {GetRandomPosInWater State.history}
in
ID=State.id Pos=RandomPt
{NewRec {NewRec State pos Pos} history RandomPt|State.history}
{NewRec {NewRec State pos Pos} history nil}
end
fun {GetRandomElement L}
......@@ -65,36 +65,31 @@ define
end
end
fun {GetPossibleDirections History Directions}
case History
of nil then
Directions
else CurrentPos=History.1 in
case Directions of nil then nil
[] east|T then
if {ValidPosition CurrentPos.x CurrentPos.y+1 History} then
east|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] west|T then
if {ValidPosition CurrentPos.x CurrentPos.y-1 History} then
west|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] south|T then
if {ValidPosition CurrentPos.x+1 CurrentPos.y History} then
south|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] north|T then
if {ValidPosition CurrentPos.x-1 CurrentPos.y History} then
north|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] surface|T then
surface|{GetPossibleDirections History T}
end
fun {GetPossibleDirections CurrentPos History Directions}
case Directions of nil then nil
[] east|T then
if {ValidPosition CurrentPos.x CurrentPos.y+1 History} then
east|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] west|T then
if {ValidPosition CurrentPos.x CurrentPos.y-1 History} then
west|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] south|T then
if {ValidPosition CurrentPos.x+1 CurrentPos.y History} then
south|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] north|T then
if {ValidPosition CurrentPos.x-1 CurrentPos.y History} then
north|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] surface|T then
surface|{GetPossibleDirections CurrentPos History T}
end
end
fun {HandleMove State move(ID Pos Direction)}
RandomDirection={GetRandomElement {GetPossibleDirections State.history AllDirections}}
RandomDirection={GetRandomElement {GetPossibleDirections State.pos State.history AllDirections}}
NewPos={UpdatePos State.pos RandomDirection}
in
ID=State.id Pos=NewPos Direction=RandomDirection
......@@ -102,7 +97,7 @@ define
of surface then
{NewRec {NewRec State pos NewPos} history nil}
else
{NewRec {NewRec State pos NewPos} history NewPos|State.history}
{NewRec {NewRec State pos NewPos} history Pos|State.history}
end
end
......@@ -166,7 +161,7 @@ define
of nil then
ID=State.id Mine=null
State
elseif {OS.rand} mod 2 == 0 then MineToExplode={GetRandomElement State.placedMines} in
elseif {OS.rand} mod 5 \= 0 then MineToExplode={GetRandomElement State.placedMines} in
ID=State.id Mine=MineToExplode
{NewRec State placedMines {List.subtract State.placedMines MineToExplode}}
else
......@@ -179,15 +174,15 @@ define
{Abs Pos1.x-Pos2.x}+{Abs Pos1.y-Pos2.y}
end
fun {DamageFromMissile MyPos MissilePos}
case {ManhattanDistance MyPos MissilePos}
fun {DamageFromExplosion MyPos ExplosionPos}
case {ManhattanDistance MyPos ExplosionPos}
of 0 then 2
[] 1 then 1
else 0 end
end
fun{HandleExplosion State ID Pos Msg}
Damage={DamageFromMissile State.pos Pos}
Damage={DamageFromExplosion State.pos Pos}
in
case Damage
of 0 then
......@@ -196,10 +191,10 @@ define
else NewLife={Max 0 State.life-Damage} in
case NewLife
of 0 then
Msg=sayDeath(State.id.id)
Msg=sayDeath(State.id)
{NewRec State life 0}
else
Msg=sayDamageTaken(State.id.id Damage NewLife)
Msg=sayDamageTaken(State.id Damage NewLife)
{NewRec State life NewLife}
end
end
......@@ -218,11 +213,13 @@ define
[] saySurface(ID)|T then %% Ignored
{DeadTreatStream T State}
[] sayMove(ID Direct)|T then %% Ignored
ID=null
{DeadTreatStream T State}
[] chargeItem(ID Item)|T then
ID=null
{DeadTreatStream T State}
[] isDead(Answer)|T then
Answer=true
{DeadTreatStream T State}
[] fireItem(ID KindFire)|T then
ID=null
{DeadTreatStream T State}
......@@ -246,16 +243,16 @@ define
ID=null
{DeadTreatStream T State}
[] sayAnswerDrone(Drone ID Answer)|T then %% Ignore
ID=null
{DeadTreatStream T State}
[] sayPassingSonar(ID Resp)|T then
ID=null
{DeadTreatStream T State}
[] sayAnswerSonar(ID Answer)|T then %% Ignore
ID=null
{DeadTreatStream T State}
else
{AliveTreatStream Stream State}
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{DeadTreatStream T State}
[] sayDeath(ID)|T then %% Ignore
{DeadTreatStream T State}
end
end
......@@ -280,6 +277,9 @@ define
[] sayMove(ID Direct)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)}
{AliveTreatStream T State}
[] isDead(Answer)|T then
Answer=false
{AliveTreatStream T State}
[] chargeItem(ID Item)|T then NewState in
{System.show 'Player'#State.id.id#'received'#chargeItem(ID Item)}
NewState={HandleChargeItem State chargeItem(ID Item)}
......@@ -338,8 +338,9 @@ define
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDamageTaken(ID Damage LifeLeft)}
{AliveTreatStream T State}
else
{AliveTreatStream Stream State}
[] sayDeath(ID)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDeath(ID)}
{AliveTreatStream T State}
end
end
......
......@@ -46,7 +46,7 @@ define
RandomPt = {GetRandomPosInWater State.history}
in
ID=State.id Pos=RandomPt
{NewRec {NewRec State pos Pos} history RandomPt|State.history}
{NewRec {NewRec State pos Pos} history nil}
end
fun {GetRandomElement L}
......@@ -65,36 +65,31 @@ define
end
end
fun {GetPossibleDirections History Directions}
case History
of nil then
Directions
else CurrentPos=History.1 in
case Directions of nil then nil
[] east|T then
if {ValidPosition CurrentPos.x CurrentPos.y+1 History} then
east|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] west|T then
if {ValidPosition CurrentPos.x CurrentPos.y-1 History} then
west|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] south|T then
if {ValidPosition CurrentPos.x+1 CurrentPos.y History} then
south|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] north|T then
if {ValidPosition CurrentPos.x-1 CurrentPos.y History} then
north|{GetPossibleDirections History T}
else {GetPossibleDirections History T} end
[] surface|T then
surface|{GetPossibleDirections History T}
end
fun {GetPossibleDirections CurrentPos History Directions}
case Directions of nil then nil
[] east|T then
if {ValidPosition CurrentPos.x CurrentPos.y+1 History} then
east|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] west|T then
if {ValidPosition CurrentPos.x CurrentPos.y-1 History} then
west|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] south|T then
if {ValidPosition CurrentPos.x+1 CurrentPos.y History} then
south|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] north|T then
if {ValidPosition CurrentPos.x-1 CurrentPos.y History} then
north|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] surface|T then
surface|{GetPossibleDirections CurrentPos History T}
end
end
fun {HandleMove State move(ID Pos Direction)}
RandomDirection={GetRandomElement {GetPossibleDirections State.history AllDirections}}
RandomDirection={GetRandomElement {GetPossibleDirections State.pos State.history AllDirections}}
NewPos={UpdatePos State.pos RandomDirection}
in
ID=State.id Pos=NewPos Direction=RandomDirection
......@@ -102,7 +97,7 @@ define
of surface then
{NewRec {NewRec State pos NewPos} history nil}
else
{NewRec {NewRec State pos NewPos} history NewPos|State.history}
{NewRec {NewRec State pos NewPos} history Pos|State.history}
end
end
......@@ -166,7 +161,7 @@ define
of nil then
ID=State.id Mine=null
State
elseif {OS.rand} mod 2 == 0 then MineToExplode={GetRandomElement State.placedMines} in
elseif {OS.rand} mod 5 \= 0 then MineToExplode={GetRandomElement State.placedMines} in
ID=State.id Mine=MineToExplode
{NewRec State placedMines {List.subtract State.placedMines MineToExplode}}
else
......@@ -179,15 +174,15 @@ define
{Abs Pos1.x-Pos2.x}+{Abs Pos1.y-Pos2.y}
end
fun {DamageFromMissile MyPos MissilePos}
case {ManhattanDistance MyPos MissilePos}
fun {DamageFromExplosion MyPos ExplosionPos}
case {ManhattanDistance MyPos ExplosionPos}
of 0 then 2
[] 1 then 1
else 0 end
end
fun{HandleExplosion State ID Pos Msg}
Damage={DamageFromMissile State.pos Pos}
Damage={DamageFromExplosion State.pos Pos}
in
case Damage
of 0 then
......@@ -196,10 +191,10 @@ define
else NewLife={Max 0 State.life-Damage} in
case NewLife
of 0 then
Msg=sayDeath(State.id.id)
Msg=sayDeath(State.id)
{NewRec State life 0}
else
Msg=sayDamageTaken(State.id.id Damage NewLife)
Msg=sayDamageTaken(State.id Damage NewLife)
{NewRec State life NewLife}
end
end
......@@ -218,11 +213,13 @@ define
[] saySurface(ID)|T then %% Ignored
{DeadTreatStream T State}
[] sayMove(ID Direct)|T then %% Ignored
ID=null
{DeadTreatStream T State}
[] chargeItem(ID Item)|T then
ID=null
{DeadTreatStream T State}
[] isDead(Answer)|T then
Answer=true
{DeadTreatStream T State}
[] fireItem(ID KindFire)|T then
ID=null
{DeadTreatStream T State}
......@@ -246,16 +243,16 @@ define
ID=null
{DeadTreatStream T State}
[] sayAnswerDrone(Drone ID Answer)|T then %% Ignore
ID=null
{DeadTreatStream T State}
[] sayPassingSonar(ID Resp)|T then
ID=null
{DeadTreatStream T State}
[] sayAnswerSonar(ID Answer)|T then %% Ignore
ID=null
{DeadTreatStream T State}
else
{AliveTreatStream Stream State}
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{DeadTreatStream T State}
[] sayDeath(ID)|T then %% Ignore
{DeadTreatStream T State}
end
end
......@@ -280,6 +277,9 @@ define
[] sayMove(ID Direct)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)}
{AliveTreatStream T State}
[] isDead(Answer)|T then
Answer=false
{AliveTreatStream T State}
[] chargeItem(ID Item)|T then NewState in
{System.show 'Player'#State.id.id#'received'#chargeItem(ID Item)}
NewState={HandleChargeItem State chargeItem(ID Item)}
......@@ -338,8 +338,9 @@ define
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDamageTaken(ID Damage LifeLeft)}
{AliveTreatStream T State}
else
{AliveTreatStream Stream State}
[] sayDeath(ID)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDeath(ID)}
{AliveTreatStream T State}
end
end
......
functor
import
Input
OS
System
export
portPlayer:StartPlayer
define
StartPlayer
TreatStream
AllDirections = [east west north south surface]
AllWeapons = [missile sonar drone mine]
fun{NewRec Rec Feature Value}
NewRecord={Record.clone Rec}
in
{List.forAll {Record.arity NewRecord} proc{$ Feat}
if Feat==Feature then NewRecord.Feat=Value
else NewRecord.Feat=Rec.Feat end
end}
NewRecord
end
fun{ValidPosition X Y History}
if X < 1 orelse X > Input.nRow then
false
elseif Y < 1 orelse Y > Input.nColumn then
false
else
{And {Not {List.nth {List.nth Input.map X} Y}==1}
{Not {List.member pt(x:X y:Y) History}}}
end
end
fun{GetRandomPosInWater History}
RandomX = ({OS.rand} mod Input.nRow) + 1
RandomY = ({OS.rand} mod Input.nColumn) + 1
in
if {Not {ValidPosition RandomX RandomY History}} then
{GetRandomPosInWater History}
else pt(x:RandomX y:RandomY)
end
end
fun {HandleInitPosition State initPosition(ID Pos)}
RandomPt = {GetRandomPosInWater State.history}
in
ID=State.id Pos=RandomPt
{NewRec {NewRec State pos Pos} history nil}
end
fun {GetRandomElement L}
Idx=({OS.rand} mod {List.length L}) + 1
in
{List.nth L Idx}
end
fun {UpdatePos pt(x:X y:Y) Direction}
case Direction
of east then pt(x:X y:Y+1)
[] west then pt(x:X y:Y-1)
[] south then pt(x:X+1 y:Y)
[] north then pt(x:X-1 y:Y)
[] surface then pt(x:X y:Y)
end
end
fun {GetPossibleDirections CurrentPos History Directions}
case Directions of nil then nil
[] east|T then
if {ValidPosition CurrentPos.x CurrentPos.y+1 History} then
east|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] west|T then
if {ValidPosition CurrentPos.x CurrentPos.y-1 History} then
west|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] south|T then
if {ValidPosition CurrentPos.x+1 CurrentPos.y History} then
south|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] north|T then
if {ValidPosition CurrentPos.x-1 CurrentPos.y History} then
north|{GetPossibleDirections CurrentPos History T}
else {GetPossibleDirections CurrentPos History T} end
[] surface|T then
surface|{GetPossibleDirections CurrentPos History T}
end
end
fun {HandleMove State move(ID Pos Direction)}
RandomDirection={GetRandomElement {GetPossibleDirections State.pos State.history AllDirections}}
NewPos={UpdatePos State.pos RandomDirection}
in
ID=State.id Pos=NewPos Direction=RandomDirection
case RandomDirection
of surface then
{NewRec {NewRec State pos NewPos} history nil}
else
{NewRec {NewRec State pos NewPos} history Pos|State.history}
end
end
fun {GetNewChargeFireItem Item}
case Item
of mine then '#'(fireItem:mine({GetRandomPosInWater nil}) charge:0)
[] missile then '#'(fireItem:missile({GetRandomPosInWater nil}) charge:0)
[] drone then Rdm={GetRandomPosInWater nil} in
if {OS.rand} mod 2 == 0 then '#'(fireItem:drone(row Rdm.x) charge:0)
else '#'(fireItem:drone(column Rdm.y) charge:0) end
[] sonar then '#'(fireItem:sonar charge:0)
end
end
fun {CheckFireItemReady '#'(fireItem:FireItem charge:NbCharge)}
Input.{Record.label FireItem}==NbCharge
end
fun{HandleChargeItem State chargeItem(ID Item)}
ToCharge={GetRandomElement State.chargingItems}
AfterCharge={NewRec ToCharge charge ToCharge.charge+1}
NewChargingItems
in
if {CheckFireItemReady AfterCharge} then NewChargingItem={GetNewChargeFireItem {Record.label AfterCharge.fireItem}} in
ID=State.id Item={Record.label AfterCharge.fireItem}
NewChargingItems={List.map State.chargingItems fun{$ Item}
if Item==ToCharge then NewChargingItem
else Item end
end}
{NewRec {NewRec State chargingItems NewChargingItems} chargedItems AfterCharge.fireItem|State.chargedItems}
else
NewChargingItems={List.map State.chargingItems fun{$ Item}
if Item==ToCharge then AfterCharge
else Item end
end}
ID=State.id Item=null
{NewRec State chargingItems NewChargingItems}
end
end
fun {HandleFireItem State fireItem(ID KindFire)}
case State.chargedItems
of nil then
ID=State.id KindFire=null
State
elseif {OS.rand} mod 2 == 0 then ToFire={GetRandomElement State.chargedItems} in
ID=State.id KindFire=ToFire
case {Record.label KindFire} of mine then
{NewRec {NewRec State chargedItems {List.subtract State.chargedItems ToFire}} placedMines KindFire|State.placedMines}
else
{NewRec State chargedItems {List.subtract State.chargedItems ToFire}}
end
else
ID=State.id KindFire=null
State
end
end
fun{HandleFireMine State fireMine(ID Mine)}
case State.placedMines
of nil then
ID=State.id Mine=null
State
elseif {OS.rand} mod 5 \= 0 then MineToExplode={GetRandomElement State.placedMines} in
ID=State.id Mine=MineToExplode
{NewRec State placedMines {List.subtract State.placedMines MineToExplode}}
else
ID=State.id Mine=null
State
end
end
fun {ManhattanDistance Pos1 Pos2}
{Abs Pos1.x-Pos2.x}+{Abs Pos1.y-Pos2.y}
end
fun {DamageFromExplosion MyPos ExplosionPos}
case {ManhattanDistance MyPos ExplosionPos}
of 0 then 2
[] 1 then 1
else 0 end
end
fun{HandleExplosion State ID Pos Msg}
Damage={DamageFromExplosion State.pos Pos}
in
case Damage
of 0 then
Msg=null
State
else NewLife={Max 0 State.life-Damage} in
case NewLife
of 0 then
Msg=sayDeath(State.id)
{NewRec State life 0}
else
Msg=sayDamageTaken(State.id Damage NewLife)
{NewRec State life NewLife}
end
end
end
proc{DeadTreatStream Stream State}
case Stream
of initPosition(ID Pos)|T then
ID=null
{DeadTreatStream T State}
[] move(ID Pos Direction)|T then
ID=null
{DeadTreatStream T State}
[] dive|T then %% Ignored
{DeadTreatStream T State}
[] saySurface(ID)|T then %% Ignored
{DeadTreatStream T State}
[] sayMove(ID Direct)|T then %% Ignored
{DeadTreatStream T State}
[] chargeItem(ID Item)|T then
ID=null
{DeadTreatStream T State}
[] isDead(Answer)|T then
Answer=true
{DeadTreatStream T State}
[] fireItem(ID KindFire)|T then
ID=null
{DeadTreatStream T State}
[] fireMine(ID Mine)|T then
ID=null
{DeadTreatStream T State}
[] sayCharge(ID KindItem)|T then %% Ignored
{DeadTreatStream T State}
[] sayMinePlaced(ID)|T then %% Ignored
{DeadTreatStream T State}
[] sayMissileExplode(ID Pos Msg)|T then
Msg=null
{DeadTreatStream T State}
[] sayMineExplode(ID Pos Msg)|T then
Msg=null
{DeadTreatStream T State}
[] sayPassingDrone(drone(row X) ID Answer)|T then
ID=null
{DeadTreatStream T State}
[] sayPassingDrone(drone(column Y) ID Answer)|T then
ID=null
{DeadTreatStream T State}
[] sayAnswerDrone(Drone ID Answer)|T then %% Ignore
{DeadTreatStream T State}
[] sayPassingSonar(ID Resp)|T then
ID=null
{DeadTreatStream T State}
[] sayAnswerSonar(ID Answer)|T then %% Ignore
{DeadTreatStream T State}
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{DeadTreatStream T State}
[] sayDeath(ID)|T then %% Ignore
{DeadTreatStream T State}
end
end
proc{AliveTreatStream Stream State}
case Stream
of initPosition(ID Pos)|T then NewState in
{System.show 'Player'#State.id.id#'received'#initPosition(ID Pos)}
NewState={HandleInitPosition State initPosition(ID Pos)}
{System.show 'Player'#State.id.id#'replied'#initPosition(ID Pos)}
{AliveTreatStream T NewState}
[] move(ID Pos Direction)|T then NewState in
{System.show 'Player'#State.id.id#'received'#move(ID Pos Direction)}
NewState={HandleMove State move(ID Pos Direction)}
{System.show 'Player'#State.id.id#'replied'#move(ID Pos Direction)}
{AliveTreatStream T NewState}
[] dive|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#dive}
{AliveTreatStream T State}
[] saySurface(ID)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#saySurface(ID)}
{AliveTreatStream T State}
[] sayMove(ID Direct)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)}
{AliveTreatStream T State}
[] isDead(Answer)|T then
Answer=false
{AliveTreatStream T State}
[] chargeItem(ID Item)|T then NewState in
{System.show 'Player'#State.id.id#'received'#chargeItem(ID Item)}
NewState={HandleChargeItem State chargeItem(ID Item)}
{System.show 'Player'#State.id.id#'replied'#chargeItem(ID Item)}
{AliveTreatStream T NewState}
[] fireItem(ID KindFire)|T then NewState in
{System.show 'Player'#State.id.id#'received'#fireItem(ID KindFire)}
NewState={HandleFireItem State fireItem(ID KindFire)}
{System.show 'Player'#State.id.id#'replied'#fireItem(ID KindFire)}
{AliveTreatStream T NewState}
[] fireMine(ID Mine)|T then NewState in
{System.show 'Player'#State.id.id#'received'#fireMine(ID Mine)}
NewState={HandleFireMine State fireMine(ID Mine)}
{System.show 'Player'#State.id.id#'replied'#fireMine(ID Mine)}
{AliveTreatStream T NewState}
[] sayCharge(ID KindItem)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#sayCharge(ID KindItem)}
{AliveTreatStream T State}
[] sayMinePlaced(ID)|T then %% Ignored
{System.show 'Player'#State.id.id#'received'#sayMinePlaced(ID)}
{AliveTreatStream T State}
[] sayMissileExplode(ID Pos Msg)|T then NewState in
{System.show 'Player'#State.id.id#'received'#sayMissileExplode(ID Pos Msg)}
NewState={HandleExplosion State ID Pos Msg}
{System.show 'Player'#State.id.id#'replied'#sayMissileExplode(ID Pos Msg)}
if NewState.life > 0 then {AliveTreatStream T NewState}
else {DeadTreatStream T NewState} end
[] sayMineExplode(ID Pos Msg)|T then NewState in
{System.show 'Player'#State.id.id#'received'#sayMineExplode(ID Pos Msg)}
NewState={HandleExplosion State ID Pos Msg}
{System.show 'Player'#State.id.id#'replied'#sayMineExplode(ID Pos Msg)}
if NewState.life > 0 then {AliveTreatStream T NewState}
else {DeadTreatStream T NewState} end
[] sayPassingDrone(drone(row X) ID Answer)|T then
{System.show 'Player'#State.id.id#'received'#sayPassingDrone(drone(row X) ID Answer)}
ID=State.id.id
Answer=State.pos.x==X
{System.show 'Player'#State.id.id#'replied'#sayPassingDrone(drone(row X) ID Answer)}
{AliveTreatStream T State}
[] sayPassingDrone(drone(column Y) ID Answer)|T then
{System.show 'Player'#State.id.id#'received'#sayPassingDrone(drone(column Y) ID Answer)}
ID=State.id.id
Answer=State.pos.y==Y
{System.show 'Player'#State.id.id#'replied'#sayPassingDrone(drone(column Y) ID Answer)}
{AliveTreatStream T State}
[] sayAnswerDrone(Drone ID Answer)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayAnswerDrone(Drone ID Answer)}
{AliveTreatStream T State}
[] sayPassingSonar(ID Resp)|T then
ID=State.id.id Resp=pt(x:State.pos.x y:{Max 0 State.pos.y})
{System.show 'Player'#State.id.id#'received'#sayPassingSonar(ID Resp)}
{AliveTreatStream T State}
[] sayAnswerSonar(ID Answer)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayAnswerSonar(ID Answer)}
{AliveTreatStream T State}
[] sayDamageTaken(ID Damage LifeLeft)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDamageTaken(ID Damage LifeLeft)}
{AliveTreatStream T State}
[] sayDeath(ID)|T then %% Ignore
{System.show 'Player'#State.id.id#'received'#sayDeath(ID)}
{AliveTreatStream T State}
end
end
fun{StartPlayer Color ID}
Stream
Port
in
{NewPort Stream Port}
thread
{AliveTreatStream Stream '#'(id:id(id:ID color:Color name:name)
life:Input.maxDamage
pos:pt(x:0 y:0)
chargingItems:[ {GetNewChargeFireItem mine} {GetNewChargeFireItem missile}
{GetNewChargeFireItem sonar} {GetNewChargeFireItem drone} ]
chargedItems:nil
placedMines:nil
history:nil)}
end
Port
end
end
\ No newline at end of file
......@@ -2,6 +2,7 @@ functor
import
Player000Basic
Player001Basic
Player002Basic
export
playerGenerator:PlayerGenerator
define
......@@ -13,6 +14,8 @@ in
{Player000Basic.portPlayer Color ID}
[] player001basic then
{Player001Basic.portPlayer Color ID}
[] player002basic then
{Player002Basic.portPlayer Color ID}
end
end
end
\ No newline at end of file
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter