From 5de7f09b40bc6fa4a8f5de04686e9f3666f231ec Mon Sep 17 00:00:00 2001
From: Vany Ingenzi <ingenzi@intel16.info.ucl.ac.be>
Date: Fri, 10 Dec 2021 07:05:23 +0100
Subject: [PATCH] Working randomPlayers with some bigs yet to fix

---
 Main.oz           |  30 +++---
 Player000Basic.oz | 249 ++++++++++++++++++++++++++++++++++++++++-----
 Player001Basic.oz | 251 ++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 477 insertions(+), 53 deletions(-)

diff --git a/Main.oz b/Main.oz
index cd666c3..fb29da4 100644
--- a/Main.oz
+++ b/Main.oz
@@ -32,7 +32,7 @@ define
     end
     
     fun {ModifyOnlyCurrent Players Current F}
-        {List.Map Players fun{$ Player} if Player==Current then {F Player} else Player end end}
+        {List.map Players fun{$ Player} if Player==Current then {F Player} else Player end end}
     end
 
     %% NextPlayers      : The next players to play
@@ -72,6 +72,7 @@ define
         case Players of nil then skip
         [] Player|OtherPlayers then
             {Send Player.port Msg}
+            {Broadcast OtherPlayers Msg}
         end
     end
 
@@ -94,7 +95,7 @@ define
                                     {Send Player.port sayMissileExplode(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)}
@@ -105,16 +106,17 @@ define
 
 
     proc{ManagingDroneFiring Players SenderPlayer Drone}
-        {List.forAll Players proc{$ Player} ID Resp in
+        {List.forAll Players    proc{$ Player} ID Resp in
                                     {Send Player.port sayPassingDrone(Drone ID Resp)}
-                                    {Send SenderPlayer.port Resp}
+                                    {Send SenderPlayer.port sayAnswerDrone(Drone ID Resp)}
                                 end}
     end
 
     proc{ManagingSonarFiring Players SenderPlayer}
-        {List.forAll Players proc{$ Player} ID Resp in
-            {Send Player.port sayPassingSonar(ID Resp)}
-            {Send SenderPlayer.port Resp} end}
+        {List.forAll Players    proc{$ Player} ID Resp in
+                                    {Send Player.port sayPassingSonar(ID Resp)}
+                                    {Send SenderPlayer.port sayAnswerSonar(ID Resp)}
+                                end}
     end
 
     fun {TurnByTurn345 Players CurrentIndex Next}
@@ -127,33 +129,35 @@ define
         of surface then 
             NewPlayers={ModifyOnlyCurrent Players CurrentPlayer SetNbSurfaceOne}
             {Broadcast NewPlayers saySurface(ID)}       {Send GUI_PORT surface(ID)}
-            Next=9 NewPlayers
+            Next=9 
+            NewPlayers
         else
             {Broadcast Players sayMove(ID Direction)} 
             {Send GUI_PORT movePlayer(ID Pos)}
-            Next=6 Players
+            Next=6 
+            Players
         end
     end
 
     proc {TurnByTurn6 Players CurrentIndex}
-        CurrentPlayer=Players.CurrentIndex
+        CurrentPlayer={List.nth Players CurrentIndex}
         ID KindItem 
     in 
         {Send CurrentPlayer.port chargeItem(ID KindItem)}
         case KindItem of null then skip
         else 
-            {Broadcast Players sayCharged(ID KindItem)}
+            {Broadcast Players sayCharge(ID KindItem)}
         end
     end
 
     proc {TurnByTurn78 Players CurrentIndex}
-        CurrentPlayer=Players.CurrentIndex
+        CurrentPlayer={List.nth Players CurrentIndex}
         ID KindFire
     in 
         {Send CurrentPlayer.port fireItem(ID KindFire)}
         case KindFire of null then skip
         [] mine(Position) then Id Mine in 
-            {Send GUI_PORT putItem(ID Position)}    {Broadcast Players sayMinePlace(ID)}
+            {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 
diff --git a/Player000Basic.oz b/Player000Basic.oz
index 22e4a57..0e09786 100644
--- a/Player000Basic.oz
+++ b/Player000Basic.oz
@@ -106,56 +106,259 @@ define
         end
     end
 
-    fun {GetNewFireItem Item}
+    fun {GetNewChargeFireItem Item}
         case Item 
-        of mine then UndefinedX UndefinedY in Mine({})
+        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 FireItem={GetNewFireItem {GetRandomElement AllWeapons}}
-            {NewRec State chargeItems }
+        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{StartPlayer Color ID}
-        Stream
-        Port 
+    fun{HandleFireMine State fireMine(ID Mine)}
+        case State.placedMines 
+        of nil then 
+            ID=State.id Mine=null
+            State
+        elseif {OS.rand} mod 2 == 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 {DamageFromMissile MyPos MissilePos}
+        case {ManhattanDistance MyPos MissilePos}
+        of 0 then 2 
+        [] 1 then 1
+        else 0 end
+    end
+
+    fun{HandleExplosion State ID Pos Msg}
+        Damage={DamageFromMissile State.pos Pos}
     in
-        {NewPort Stream Port}
-        thread
-            {TreatStream Stream '#'(id:id(id:ID color:Color name:name) 
-                                    pos:pt(x:0 y:0)
-                                    chargedItems:nil %%[ ... '#'(fireItem:<fireItem> charge:<int>) ... ]
-                                    history:nil)}
+        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.id) 
+                {NewRec State life 0}
+            else 
+                Msg=sayDamageTaken(State.id.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
+            ID=null
+            {DeadTreatStream T State}
+        [] chargeItem(ID Item)|T then 
+            ID=null
+            {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
+            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}
         end
-        Port
     end
 
-    proc{TreatStream Stream State}
+    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)}
-            {TreatStream T NewState}
+            {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)}
-            {TreatStream T NewState}
+            {AliveTreatStream T NewState}
         [] dive|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#dive}
-            {TreatStream T State}
+            {AliveTreatStream T State}
         [] saySurface(ID)|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#saySurface(ID)}
-            {TreatStream T State}
+            {AliveTreatStream T State}
         [] sayMove(ID Direct)|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)}
-            {TreatStream T State}
-        [] chargeItem(ID Item) then 
-            ...
+            {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}
         else 
-            {TreatStream Stream State}
+            {AliveTreatStream Stream 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/Player001Basic.oz b/Player001Basic.oz
index 85a09b5..0e09786 100644
--- a/Player001Basic.oz
+++ b/Player001Basic.oz
@@ -9,6 +9,7 @@ define
     StartPlayer
     TreatStream
     AllDirections = [east west north south surface]
+    AllWeapons    = [missile sonar drone mine]
 
     fun{NewRec Rec Feature Value}
         NewRecord={Record.clone Rec}
@@ -105,43 +106,259 @@ define
         end
     end
 
-    fun{StartPlayer Color ID}
-        Stream
-        Port 
+    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 2 == 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 {DamageFromMissile MyPos MissilePos}
+        case {ManhattanDistance MyPos MissilePos}
+        of 0 then 2 
+        [] 1 then 1
+        else 0 end
+    end
+
+    fun{HandleExplosion State ID Pos Msg}
+        Damage={DamageFromMissile State.pos Pos}
     in
-        {NewPort Stream Port}
-        thread
-            {TreatStream Stream '#'(id:id(id:ID color:Color name:name) 
-                                    pos:pt(x:0 y:0)
-                                    items:'#'(missile:0 sonar:0 drone:0 mine:0)
-                                    history:nil)}
+        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.id) 
+                {NewRec State life 0}
+            else 
+                Msg=sayDamageTaken(State.id.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
+            ID=null
+            {DeadTreatStream T State}
+        [] chargeItem(ID Item)|T then 
+            ID=null
+            {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
+            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}
         end
-        Port
     end
 
-    proc{TreatStream Stream State}
+    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)}
-            {TreatStream T NewState}
+            {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)}
-            {TreatStream T NewState}
+            {AliveTreatStream T NewState}
         [] dive|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#dive}
-            {TreatStream T State}
+            {AliveTreatStream T State}
         [] saySurface(ID)|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#saySurface(ID)}
-            {TreatStream T State}
+            {AliveTreatStream T State}
         [] sayMove(ID Direct)|T then %% Ignored
             {System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)}
-            {TreatStream T State}
+            {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}
         else 
-            {TreatStream Stream State}
+            {AliveTreatStream Stream 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
-- 
GitLab