diff --git a/Input.oz b/Input.oz index 0148ac58bed1c8e3f33d451f423d8a937fcf43aa..6d5d91525e4001498149e4248e5f767b25f757c9 100644 --- a/Input.oz +++ b/Input.oz @@ -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 %%%% diff --git a/Main.oz b/Main.oz index fb29da41a0609a117367b4865ab36c09df7ac317..a6c3725dae3d0ca4265def1f0a13a58979baad86 100644 --- a/Main.oz +++ b/Main.oz @@ -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 diff --git a/Player000Basic.oz b/Player000Basic.oz index 0e097861fc31357a1cada67dd730a9d990886e22..9dce76bd5d82894ed15cc55b95bb41e46ba06624 100644 --- a/Player000Basic.oz +++ b/Player000Basic.oz @@ -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 diff --git a/Player001Basic.oz b/Player001Basic.oz index 0e097861fc31357a1cada67dd730a9d990886e22..9dce76bd5d82894ed15cc55b95bb41e46ba06624 100644 --- a/Player001Basic.oz +++ b/Player001Basic.oz @@ -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 diff --git a/Player002Basic.oz b/Player002Basic.oz new file mode 100644 index 0000000000000000000000000000000000000000..9dce76bd5d82894ed15cc55b95bb41e46ba06624 --- /dev/null +++ b/Player002Basic.oz @@ -0,0 +1,365 @@ +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 diff --git a/PlayerManager.oz b/PlayerManager.oz index 15209355c7e79d2feb349b05d4a06fcff711ed31..4b4d45d457560e3467c8b693a6770909b1dc1be3 100644 --- a/PlayerManager.oz +++ b/PlayerManager.oz @@ -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