diff --git a/Input.oz b/Input.oz index 69711ff46fd0cb804333e186b38f8f831f6e53cd..0148ac58bed1c8e3f33d451f423d8a937fcf43aa 100644 --- a/Input.oz +++ b/Input.oz @@ -50,19 +50,24 @@ in %%%% Description of the map %%%% - NRow = 5 - NColumn = 10 - Map = [[0 0 0 0 0 0 0 0 0 0] - [0 0 0 0 0 0 0 0 0 0] - [0 0 0 0 0 0 0 0 0 0] - [0 0 0 0 0 0 1 0 0 0] - [0 0 0 0 0 0 0 0 0 0]] + NRow = 10 + NColumn = 20 + Map = [[0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0] + [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0] + [0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0] + [0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0] + [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] + [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] + [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0] + [0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0]] %%%% Players description %%%% NbPlayers = 2 - Players = [player000basic player001basic] - Colors = [green black] + Players = [player000basic player001basic] + Colors = [black c(245 88 203)] %%%% Surface time/turns %%%% @@ -87,7 +92,6 @@ in MaxDistanceMissile = 4 %%%% Waiting time for the GUI between each effect %%%% - - GUIDelay = 500 % ms + GUIDelay = 100 % ms end \ No newline at end of file diff --git a/Main.oz b/Main.oz index 8cd15b2ce99b91be219e1cd03f7e35fd74b16c53..cd666c35d41f1f485114d4863554c3c0162843fa 100644 --- a/Main.oz +++ b/Main.oz @@ -75,21 +75,31 @@ define end end - proc {ManageMineExplosion Players Id Position} + proc {ManageMineExplosion Id Players Position} {List.forAll Players proc{$ Player} Resp in {Send Player.port sayMineExplode(Id Position Resp)} - {Wait Resp} case Resp of null then skip - else {Broadcast Players Resp} end + [] sayDeath(ID) then + {Send GUI_PORT lifeUpdate(ID 0)} + {Broadcast Players Resp} + [] sayDamageTaken(ID Damage LifeLeft) then + {Send GUI_PORT lifeUpdate(ID LifeLeft)} + {Broadcast Players Resp} + end end} end - proc {ManageMissileExplosion Players Id Position} + proc {ManageMissileExplosion Id Players Position} {List.forAll Players proc{$ Player} Resp in {Send Player.port sayMissileExplode(Id Position Resp)} - {Wait Resp} case Resp of null then skip - else {Broadcast Players Resp} end + [] sayDeath(ID) then + {Send GUI_PORT lifeUpdate(ID 0)} + {Broadcast Players Resp} + [] sayDamageTaken(ID Damage LifeLeft) then + {Send GUI_PORT lifeUpdate(ID LifeLeft)} + {Broadcast Players Resp} + end end} end @@ -113,25 +123,14 @@ define fun{SetNbSurfaceOne Player} player(port:Player.port nbSurface:1) end in {Send CurrentPlayer.port move(ID Pos Direction)} - {Wait ID} {Wait Pos} {Wait Direction} case Direction of surface then NewPlayers={ModifyOnlyCurrent Players CurrentPlayer SetNbSurfaceOne} {Broadcast NewPlayers saySurface(ID)} {Send GUI_PORT surface(ID)} Next=9 NewPlayers - [] east then - {Broadcast Players sayMove(ID Direction)} {Send GUI_PORT movePlayer(ID pt(x:Pos.x y:Pos.y+1))} - Next=6 Players - [] west then - {Broadcast Players sayMove(ID Direction)} {Send GUI_PORT movePlayer(ID pt(x:Pos.x y:Pos.y-1))} - Next=6 Players - [] north then - {Broadcast Players sayMove(ID Direction)} {Send GUI_PORT movePlayer(ID pt(x:Pos.x-1 y:Pos.y))} - Next=6 Players - [] south then - {Broadcast Players sayMove(ID Direction)} {Send GUI_PORT movePlayer(ID pt(x:Pos.x+1 y:Pos.y))} - Next=6 Players else + {Broadcast Players sayMove(ID Direction)} + {Send GUI_PORT movePlayer(ID Pos)} Next=6 Players end end @@ -141,7 +140,6 @@ define ID KindItem in {Send CurrentPlayer.port chargeItem(ID KindItem)} - {Wait ID} {Wait KindItem} case KindItem of null then skip else {Broadcast Players sayCharged(ID KindItem)} @@ -153,7 +151,6 @@ define ID KindFire in {Send CurrentPlayer.port fireItem(ID KindFire)} - {Wait ID} {Wait KindFire} case KindFire of null then skip [] mine(Position) then Id Mine in {Send GUI_PORT putItem(ID Position)} {Broadcast Players sayMinePlace(ID)} @@ -179,6 +176,7 @@ define Next1 Next345 in %% 1. + {System.show 'Turnof'#CurrentIndex} NewPlayers1 = {TurnByTurn1 Players CurrentIndex Next1} if Next1==2 then %% 2. @@ -209,6 +207,7 @@ in PlayersList={InitPlayers Input.players Input.colors 1} %%3. Ask Init Point and tell players to dive + {VisitList PlayersList proc{$ Player} ID Pos @@ -219,6 +218,7 @@ in end} %%4. Launch the game + if Input.isTurnByTurn then {TurnByTurn PlayersList 1} end diff --git a/Player000Basic.oz b/Player000Basic.oz index 9405dbdaad87276436faea827f0243cdfc1896cd..22e4a57baa6cffdc640f994641c1dcc4b0e05eab 100644 --- a/Player000Basic.oz +++ b/Player000Basic.oz @@ -2,35 +2,158 @@ functor import Input OS + System export portPlayer:StartPlayer define StartPlayer TreatStream -in + 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 RandomPt|State.history} + 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 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 + end + end + + fun {HandleMove State move(ID Pos Direction)} + RandomDirection={GetRandomElement {GetPossibleDirections 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 NewPos|State.history} + end + end + + fun {GetNewFireItem Item} + case Item + of mine then UndefinedX UndefinedY in Mine({}) + end + + fun{HandleChargeItem State chargeItem(ID Item)} + case State.chargedItems + of nil then FireItem={GetNewFireItem {GetRandomElement AllWeapons}} + {NewRec State chargeItems } + end + fun{StartPlayer Color ID} Stream Port - RandomX = ({OS.rand} mod Input.nRow) + 1 - RandomY = ({OS.rand} mod Input.nColumn) + 1 in {NewPort Stream Port} thread {TreatStream Stream '#'(id:id(id:ID color:Color name:name) - pos:pt(x:RandomX y:RandomY) - items:'#'(missile:0 sonar:0 drone:0 mine:0)) - } - + pos:pt(x:0 y:0) + chargedItems:nil %%[ ... '#'(fireItem:<fireItem> charge:<int>) ... ] + history:nil)} end Port end proc{TreatStream Stream State} case Stream - of initPosition(ID Pos)|T then - ID = State.id - Pos = State.pos - {TreatStream Stream State} + 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} + [] 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} + [] dive|T then %% Ignored + {System.show 'Player'#State.id.id#'received'#dive} + {TreatStream T State} + [] saySurface(ID)|T then %% Ignored + {System.show 'Player'#State.id.id#'received'#saySurface(ID)} + {TreatStream 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 + ... else {TreatStream Stream State} end diff --git a/Player001Basic.oz b/Player001Basic.oz index 680d1348a0f2275546ece377e8525501556a2005..85a09b5469f0f13acc94e99c12579f9e4057dba6 100644 --- a/Player001Basic.oz +++ b/Player001Basic.oz @@ -8,29 +8,138 @@ export define StartPlayer TreatStream -in + AllDirections = [east west north south surface] + + 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 RandomPt|State.history} + 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 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 + end + end + + fun {HandleMove State move(ID Pos Direction)} + RandomDirection={GetRandomElement {GetPossibleDirections 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 NewPos|State.history} + end + end + fun{StartPlayer Color ID} Stream Port - RandomX = ({OS.rand} mod Input.nRow) + 1 - RandomY = ({OS.rand} mod Input.nColumn) + 1 in {NewPort Stream Port} thread {TreatStream Stream '#'(id:id(id:ID color:Color name:name) - pos:pt(x:RandomX y:RandomY)) - } - + pos:pt(x:0 y:0) + items:'#'(missile:0 sonar:0 drone:0 mine:0) + history:nil)} end Port end proc{TreatStream Stream State} case Stream - of initPosition(ID Pos)|T then - ID = State.id - Pos = State.pos - {TreatStream Stream State} + 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} + [] 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} + [] dive|T then %% Ignored + {System.show 'Player'#State.id.id#'received'#dive} + {TreatStream T State} + [] saySurface(ID)|T then %% Ignored + {System.show 'Player'#State.id.id#'received'#saySurface(ID)} + {TreatStream T State} + [] sayMove(ID Direct)|T then %% Ignored + {System.show 'Player'#State.id.id#'received'#sayMove(ID Direct)} + {TreatStream T State} else {TreatStream Stream State} end diff --git a/statement.pdf b/statement.pdf index 04d93ec0b294548addb2d5cd89d695da778f89b7..075977410265d13c3b657d4644c9a536e22d1d99 100644 Binary files a/statement.pdf and b/statement.pdf differ