diff --git a/GUI.oz b/GUI.oz index 90a9858ac6475b7ea0ceb8a9d1bc409c582a4aa8..08e812066166f1df8f5739f7e90f439be14d862a 100644 --- a/GUI.oz +++ b/GUI.oz @@ -43,7 +43,7 @@ in Toolbar=lr(glue:we tbbutton(text:"Quit" glue:w action:toplevel#close)) Desc=grid(handle:Grid height:500 width:500) DescScore=grid(handle:GridScore height:100 width:500) - Window={QTk.build td(Toolbar Desc DescScore)} + Window={QTk.build td(title:"Captain Sonoz" Toolbar Desc DescScore)} {Window show} diff --git a/GUI.ozf b/GUI.ozf new file mode 100644 index 0000000000000000000000000000000000000000..c98e63d8232144720278350e524bf484e73f09f5 Binary files /dev/null and b/GUI.ozf differ diff --git a/HumanPlayerGUI.oz b/HumanPlayerGUI.oz new file mode 100644 index 0000000000000000000000000000000000000000..686599111694397df78ed5ab7bea7e4636c5bd0c --- /dev/null +++ b/HumanPlayerGUI.oz @@ -0,0 +1,287 @@ +functor +import + QTk at 'x-oz://system/wp/QTk.ozf' + Input + Player020Human +export + portWindow:StartWindow +define + + StartWindow + TreatStream + + RemoveItem + RemovePath + RemovePlayer + + Map = Input.map + + NRow = Input.nRow + NColumn = Input.nColumn + + DrawSubmarine + MoveSubmarine + DrawMine + RemoveMine + DrawPath + + BuildWindow + + Label + Squares + DrawMap + + StateModification + + UpdateLife +in + +%%%%% Build the initial window and set it up (call only once) + fun{BuildWindow} + Grid GridScore Toolbar Desc DescScore Window + in + Toolbar=lr(glue:we + tbbutton(text:"Quit" glue:w action:toplevel#close)) + Desc=grid(handle:Grid height:500 width:500) + DescScore=grid(handle:GridScore height:100 width:500) + Window={QTk.build td(title:"Human Player Panel" Toolbar Desc DescScore)} + + {Window show} + + % configure rows and set headers + {Grid rowconfigure(1 minsize:50 weight:0 pad:2)} + for N in 1..NRow do + {Grid rowconfigure(N+1 minsize:50 weight:0 pad:2)} + {Grid configure({Label N} row:N+1 column:1 sticky:wesn)} + end + % configure columns and set headers + {Grid columnconfigure(1 minsize:50 weight:0 pad:2)} + for N in 1..NColumn do + {Grid columnconfigure(N+1 minsize:50 weight:0 pad:2)} + {Grid configure({Label N} row:1 column:N+1 sticky:wesn)} + end + % configure scoreboard + {GridScore rowconfigure(1 minsize:50 weight:0 pad:2)} + for N in 1..(Input.nbPlayer) do + {GridScore columnconfigure(N minsize:50 weight:0 pad:2)} + end + + {DrawMap Grid} + + handle(grid:Grid score:GridScore) + end + +%%%%% Squares of water and island + Squares = square(0:label(text:"" width:1 height:1 bg:c(102 102 255)) + 1:label(text:"" borderwidth:5 relief:raised width:1 height:1 bg:c(153 76 0)) + ) + +%%%%% Labels for rows and columns + fun{Label V} + label(text:V borderwidth:5 relief:raised bg:c(255 51 51) ipadx:5 ipady:3) + end + +%%%%% Function to draw the map + proc{DrawMap Grid} + proc{DrawColumn Column M N} + case Column + of nil then skip + [] T|End then + {Grid configure(Squares.T row:M+1 column:N+1 sticky:wesn)} + {DrawColumn End M N+1} + end + end + proc{DrawRow Row M} + case Row + of nil then skip + [] T|End then + {DrawColumn T M 1} + {DrawRow End M+1} + end + end + in + {DrawRow Map 1} + end + +%%%%% Init the submarine + fun{DrawSubmarine Grid ID Position} + Handle HandlePath HandleScore X Y Id Color LabelSub LabelScore + in + pt(x:X y:Y) = Position + id(id:Id color:Color name:_) = ID + + LabelSub = label(text:"S" handle:Handle borderwidth:2 relief:raised bg:Color ipadx:2 ipady:2) + LabelScore = label(text:Input.maxDamage borderwidth:2 handle:HandleScore relief:solid bg:Color ipadx:2 ipady:2) + HandlePath = {DrawPath Grid Color X Y} + {Grid.grid configure(LabelSub row:X+1 column:Y+1 sticky:wesn)} + {Grid.score configure(LabelScore row:1 column:Id sticky:wesn)} + {HandlePath 'raise'()} + {Handle 'raise'()} + guiPlayer(id:ID score:HandleScore submarine:Handle mines:nil path:HandlePath|nil) + end + + fun{MoveSubmarine Position} + fun{$ Grid State} + ID HandleScore Handle Mine Path NewPath X Y + in + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:Path) = State + pt(x:X y:Y) = Position + NewPath = {DrawPath Grid ID.color X Y} + {Grid.grid remove(Handle)} + {Grid.grid configure(Handle row:X+1 column:Y+1 sticky:wesn)} + {NewPath 'raise'()} + {Handle 'raise'()} + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:NewPath|Path) + end + end + + fun{DrawMine Position} + fun{$ Grid State} + ID HandleScore Handle Mine Path LabelMine HandleMine X Y + in + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:Path) = State + pt(x:X y:Y) = Position + LabelMine = label(text:"M" handle:HandleMine borderwidth:5 relief:raised bg:ID.color ipadx:2 ipady:2) + {Grid.grid configure(LabelMine row:X+1 column:Y+1)} + {HandleMine 'raise'()} + {Handle 'raise'()} + guiPlayer(id:ID score:HandleScore submarine:Handle mines:mine(HandleMine Position)|Mine path:Path) + end + end + + local + fun{RmMine Grid Position List} + case List + of nil then nil + [] H|T then + if (H.2 == Position) then %ERREUR CORRIGE + {RemoveItem Grid H.1} + T + else + H|{RmMine Grid Position T} + end + end + end + in + fun{RemoveMine Position} + fun{$ Grid State} + ID HandleScore Handle Mine Path NewMine + in + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:Path) = State + NewMine = {RmMine Grid Position Mine} + guiPlayer(id:ID score:HandleScore submarine:Handle mines:NewMine path:Path) + end + end + end + + fun{DrawPath Grid Color X Y} + Handle LabelPath + in + LabelPath = label(text:"" handle:Handle bg:Color) + {Grid.grid configure(LabelPath row:X+1 column:Y+1)} + Handle + end + + proc{RemoveItem Grid Handle} + {Grid.grid forget(Handle)} + end + + + fun{RemovePath Grid State} + ID HandleScore Handle Mine Path + in + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:Path) = State + for H in Path.2 do + {RemoveItem Grid H} + end + guiPlayer(id:ID score:HandleScore submarine:Handle mines:Mine path:Path.1|nil) + end + + fun{UpdateLife Life} + fun{$ Grid State} + HandleScore + in + guiPlayer(id:_ score:HandleScore submarine:_ mines:_ path:_) = State + {HandleScore set(Life)} + State + end + end + + + fun{StateModification Grid WantedID State Fun} + case State + of nil then nil + [] guiPlayer(id:ID score:_ submarine:_ mines:_ path:_)|Next then + if (ID == WantedID) then + {Fun Grid State.1}|Next + else + State.1|{StateModification Grid WantedID Next Fun} + end + end + end + + fun{RemovePlayer Grid WantedID State} + case State + of nil then nil + [] guiPlayer(id:ID score:HandleScore submarine:Handle mines:M path:P)|Next then + if (ID == WantedID) then + {HandleScore set(0)} %ERREUR CORRIGE + for H in P do + {RemoveItem Grid H} + end + for H in M do + {RemoveItem Grid H.1} + end + {RemoveItem Grid Handle} + Next + else + State.1|{RemovePlayer Grid WantedID Next} + end + end + end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + fun{StartWindow} + Stream + Port + in + {NewPort Stream Port} + thread + {TreatStream Stream nil nil} + end + Port + end + + proc{TreatStream Stream Grid State} + case Stream + of nil|T then skip + [] buildWindow|T then NewGrid in + NewGrid = {BuildWindow} + {TreatStream T NewGrid State} + [] initPlayer(ID Position)|T then NewState in + NewState = {DrawSubmarine Grid ID Position} + {TreatStream T Grid NewState|State} + [] movePlayer(ID Position)|T then + {TreatStream T Grid {StateModification Grid ID State {MoveSubmarine Position}}} + [] lifeUpdate(ID Life)|T then + {TreatStream T Grid {StateModification Grid ID State {UpdateLife Life}}} + [] putMine(ID Position)|T then + {TreatStream T Grid {StateModification Grid ID State {DrawMine Position}}} + [] removeMine(ID Position)|T then + {TreatStream T Grid {StateModification Grid ID State {RemoveMine Position}}} + [] surface(ID)|T then + {TreatStream T Grid {StateModification Grid ID State RemovePath}} + [] removePlayer(ID)|T then + {TreatStream T Grid {RemovePlayer Grid ID State}} + [] explosion(ID Position)|T then + {TreatStream T Grid State} + [] drone(ID Drone)|T then + {TreatStream T Grid State} + [] sonar(ID)|T then + {TreatStream T Grid State} + [] _|T then + {TreatStream T Grid State} + end + end +end diff --git a/HumanPlayerGUI.ozf b/HumanPlayerGUI.ozf new file mode 100644 index 0000000000000000000000000000000000000000..b26099ffbb849808f2886dcdbfd4f3a89aa28aae Binary files /dev/null and b/HumanPlayerGUI.ozf differ diff --git a/Input.oz b/Input.oz index a9316700b67ce5a55561e56b7294a964a683a883..753bb36cd184750e244c263c29dac94ec68666a3 100644 --- a/Input.oz +++ b/Input.oz @@ -113,11 +113,11 @@ in %%%% Style of game %%%% - IsTurnByTurn = true + IsTurnByTurn = false %%%% Players description %%%% - NbPlayers = 7 + NbPlayers = 8 Players = [ player003bomberman player003memory @@ -126,7 +126,7 @@ in player020random player020hiderandseeker player038cartographer - %player069rocketman + player020human ] Colors = [ c(245 88 203) @@ -135,8 +135,8 @@ in green red c(178 102 255) - %c(0 204 204) c(204 204 0) + c(133 133 99) ] %%%% Surface time/turns %%%% diff --git a/Input.ozf b/Input.ozf new file mode 100644 index 0000000000000000000000000000000000000000..e9e1fc905a361416f2c24b329e22f9fd2e43f757 Binary files /dev/null and b/Input.ozf differ diff --git a/Main.oz b/Main.oz index c7ce69e4703db97e8a3b1fdf7160696514e3a7b4..ec3dd3be547d8af35a098e5fe0de1e4dbc093a8c 100644 --- a/Main.oz +++ b/Main.oz @@ -292,7 +292,7 @@ define [] _#surface then {Broadcast PlayersList saySurface(ID)} {Send GUI_PORT surface(ID)} - {Delay Input.turnSurface * 1000} + {Delay Input.turnSurface * 100} % Go to 1. {Simultaneous Player PlayersList} else @@ -310,50 +310,62 @@ define ID KindItem in {Send Player.port chargeItem(ID KindItem)} - case KindItem of null then + case ID#KindItem + of null#_ then + skip + [] _#null then {Delay Input.thinkMax * 100} - {Simultaneous91011 Player PlayersList} - else + {Simultaneous910 Player PlayersList} + [] _#ChargedItem then {Broadcast PlayersList sayCharge(ID KindItem)} {Delay Input.thinkMax * 100} - {Simultaneous91011 Player PlayersList} + {Simultaneous910 Player PlayersList} end end % 9. Submarine fire and/or explode an item % 10. Think - proc{Simultaneous91011 Player PlayersList} + proc{Simultaneous910 Player PlayersList} ID KindFire in {Send Player.port fireItem(ID KindFire)} case KindFire of null then {Delay Input.thinkMax * 100} - {Simultaneous Player PlayersList} + {Simultaneous1112 Player PlayersList} [] mine(Position) then - Id Mine - in {Send GUI_PORT putMine(ID Position)} {Broadcast PlayersList sayMinePlaced(ID)} - {Send Player.port fireMine(Id Mine)} - case Mine of null then - {Delay Input.thinkMax * 100} - {Simultaneous Player PlayersList} - [] mine(PosMineExploded) then - {Delay Input.thinkMax * 100} - {Send GUI_PORT removeMine(Id PosMineExploded)} - {ManageMineExplosion Id PlayersList Position} - {Simultaneous Player PlayersList} - end + {Delay Input.thinkMax * 100} + {Simultaneous1112 Player PlayersList} [] missile(Position) then {ManageMissileExplosion ID PlayersList Position} - {Simultaneous Player PlayersList} + {Delay Input.thinkMax * 100} + {Simultaneous1112 Player PlayersList} [] drone(U V) then {Send GUI_PORT drone(ID KindFire)} {ManagingDroneFiring PlayersList Player KindFire} - {Simultaneous Player PlayersList} + {Delay Input.thinkMax * 100} + {Simultaneous1112 Player PlayersList} [] sonar then {Send GUI_PORT sonar(ID)} {ManagingSonarFiring PlayersList Player} + {Delay Input.thinkMax * 100} + {Simultaneous1112 Player PlayersList} + end + end + + proc{Simultaneous1112 Player PlayersList} + Id Mine + in + {Send Player.port fireMine(Id Mine)} + case Mine + of null then + {Delay Input.thinkMax * 100} + {Simultaneous Player PlayersList} + [] pt(x:_ y:_) then + {Send GUI_PORT explosion(Id Mine)} + {ManageMineExplosion Id PlayersList Mine} + {Send GUI_PORT removeMine(Id Mine)} {Simultaneous Player PlayersList} end end diff --git a/Main.ozf b/Main.ozf new file mode 100644 index 0000000000000000000000000000000000000000..4142c5ce95deff95bb0ab6455a5d07f41012eeb8 Binary files /dev/null and b/Main.ozf differ diff --git a/Player020HiderAndSeeker.ozf b/Player020HiderAndSeeker.ozf new file mode 100644 index 0000000000000000000000000000000000000000..132622c57a1b7621dea9f65a45d1c747aa26db9a Binary files /dev/null and b/Player020HiderAndSeeker.ozf differ diff --git a/Player020Human.oz b/Player020Human.oz new file mode 100644 index 0000000000000000000000000000000000000000..f0c429a4daae77099b8dde67a2c1fb89534f1c6b --- /dev/null +++ b/Player020Human.oz @@ -0,0 +1,562 @@ +functor +import + Input + HumanPlayerGUI + PlayerManager + OS + System + QTk at 'x-oz://system/wp/QTk.ozf' +export + portPlayer:StartPlayer +define + StartPlayer + TreatStream + + + %-----------AS THE MAIN------------- + HumanPlayerGUI_Port = {HumanPlayerGUI.portWindow} + + %----------------------------------- + + + 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{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{Direc} + Direction DirecWindow + in + Direction = td(button(text:"North" action:toplevel#close return: north) + lr( button(text:"West" action:toplevel#close return: west) + button(text:"Surface" action:toplevel#close return: surface) + button(text:"East" action:toplevel#close return: east)) + button(text:"South" action:toplevel#close return: south) + ) + DirecWindow = {QTk.build Direction} + {DirecWindow show} + end + + fun{HandleInitPosition State initPosition(ID Pos)} + SetPos X Y OptionWindow T P + + in + SetPos = td(title:"Human Player Panel" + lr(entry(init:"" handle: X return: T) + entry(init:"" handle: Y return: P)) + button(text:"Set Position" action: toplevel#close)) + + OptionWindow = {QTk.build SetPos} + {OptionWindow show} + {Wait T} {Wait P} + Pos = pt(x:{String.toInt T} y:{String.toInt P}) + ID = State.id + {Send HumanPlayerGUI_Port initPlayer(ID Pos)} + {NewRec {NewRec State pos Pos} history nil} + end + + fun{HandleMove State move(ID Pos Direction)} + Resp NewPos DirecWindow Dir North West Surface East South D + + in + Dir = td(title:"Directions" + button(text:"North" action:toplevel#close return: North) + lr( button(text:"West" action:toplevel#close return: West) + button(text:"Surface" action:toplevel#close return: Surface) + button(text:"East" action:toplevel#close return: East)) + button(text:"South" action:toplevel#close return: South) + ) + DirecWindow = {QTk.build Dir} + {DirecWindow show} + if North then D = north + elseif West then D = west + elseif Surface then D = surface + elseif East then D = east + else D = south + end + + Resp = D + {Wait Resp} + + NewPos={UpdatePos State.pos Resp} + Pos=NewPos + ID = State.id + Direction = Resp + + case Direction + of surface then + {Send HumanPlayerGUI_Port surface(ID)} + {NewRec {NewRec State pos NewPos} history nil} + else + {Send HumanPlayerGUI_Port movePlayer(ID Pos)} + {NewRec {NewRec State pos NewPos} history Pos|State.history} + end + end + + fun{It} + Items ItWindow + in + Items = td(title:"Human Player Panel" + button(text:"Mine" action:toplevel#close return: mine) + button(text:"Missile" action:toplevel#close return: missile) + button(text:"Drone" action:toplevel#close return: drone) + button(text:"Sonar" action:toplevel#close return: sonar) + button(text:"Nothing" action:toplevel#close return: nil)) + ItWindow = {QTk.build Items} + {ItWindow show} + 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 {AllPosibilitiesPoints P NRow NColumn Acc} + if Input.nRow==NRow andthen Input.nColumn==NColumn then Acc + elseif NRow==Input.nRow then Point=pt(x:NRow y:NColumn) in + if {ValidPosition NRow NColumn nil} andthen {P Point} then + {AllPosibilitiesPoints P 1 NColumn+1 Point|Acc} + else + {AllPosibilitiesPoints P 1 NColumn+1 Acc} + end + else Point=pt(x:NRow y:NColumn) in + if {ValidPosition NRow NColumn nil} andthen {P Point} then + {AllPosibilitiesPoints P NRow+1 NColumn Point|Acc} + else + {AllPosibilitiesPoints P NRow+1 NColumn Acc} + end + end + end + + fun {RandomValidMinePos CurrentPos} + fun {Predicate Pt} + Dist={ManhattanDistance CurrentPos Pt} + in + {And Dist>=Input.minDistanceMine Dist=<Input.maxDistanceMine} + end + + Possibilities={AllPosibilitiesPoints Predicate 1 1 nil} + in + {GetRandomElement Possibilities} + 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{AskMissilePos History} + MissilePosition U V MissileWindow Z A Pos + + in + MissilePosition = td(title:"Ask Missile Position" + lr(entry(init:"" handle: U return: Z) + entry(init:"" handle: V return: A)) + button(text:"Set Position" action: toplevel#close)) + + MissileWindow = {QTk.build MissilePosition} + {MissileWindow show} + {Wait Z} {Wait A} + Pos = pt(x:{String.toInt Z} y:{String.toInt A}) + + if {Not {ValidPosition Pos.x Pos.y History}} then + {AskMissilePos History} + else Pos + end + end + + fun {GetNewChargeFireItemRandom 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 {GetNewChargeFireItem Item} + case Item + of mine then '#'(fireItem:mine({GetRandomPosInWater nil}) charge:0) + [] missile then '#'(fireItem:missile({AskMissilePos 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)} + Add Var Resp Mine Missile Drone Sonar NewChargingItems Items ItWindow ToCharge AfterCharge + in + Items = td(title:"Charge an Item" + lr(button(text:"Mine" action:toplevel#close return: Mine) + button(text:"Missile" action:toplevel#close return: Missile) + button(text:"Drone" action:toplevel#close return: Drone) + button(text:"Sonar" action:toplevel#close return: Sonar))) + ItWindow = {QTk.build Items} + {ItWindow show} + + if Mine then Var = {GetNewChargeFireItem mine} + Item = Var.fireItem + elseif Missile then Var = {GetNewChargeFireItem missile} + Item = Var.fireItem + elseif Drone then Var = {GetNewChargeFireItem drone} + Item = Var.fireItem + else + Var = {GetNewChargeFireItem sonar} + Item = Var.fireItem + end + + Resp = Var + ToCharge = Resp + Add = ToCharge.charge + 1 + AfterCharge = {NewRec ToCharge charge Add} + + NewChargingItems={List.map State.chargingItems fun{$ Item} + if Item==ToCharge then AfterCharge + else Item end + end} + + ID=State.id + Item=AfterCharge.fireItem + {NewRec {NewRec State chargingItems NewChargingItems} chargedItems AfterCharge.fireItem|State.chargedItems} + end + + fun {SearchForItem L Label} + case L + of T1|T2 then + if Label == {Record.label T1} then T1 + else + {SearchForItem T2 Label} + end + [] nil then nil + end + + end + + fun {HandleFireItem State fireItem(ID KindFire)} + case State.chargedItems + of nil then + ID=State.id + KindFire=null + State + else + NewState Search Var OptionWindow Items ItWindow Mine Missile Drone Sonar Nothing + in + Items = td(title:"Fire an Item" + lr(button(text:"Mine" action:toplevel#close return: Mine) + button(text:"Missile" action:toplevel#close return: Missile) + button(text:"Drone" action:toplevel#close return: Drone) + button(text:"Sonar" action:toplevel#close return: Sonar) + button(text:"Nothing" action:toplevel#close return: Nothing))) + ItWindow = {QTk.build Items} + {ItWindow show} + + if Mine then Var = mine + elseif Missile then Var = missile + elseif Drone then Var = drone + elseif Sonar then Var = sonar + else Var = nil + end + + case State.chargedItems#Var + of nil#_ then + ID=State.id KindFire=null + State + [] (missile(Position)|T1)#missile then + ID=State.id KindFire=missile(Position) + {NewRec State chargedItems {List.subtract State.chargedItems KindFire}} + [] (mine(Position)|T1)#mine then + ID=State.id KindFire = mine(Position) + {Send HumanPlayerGUI_Port putMine(ID Position)} + NewState = {NewRec State chargedItems {List.subtract State.chargedItems KindFire}} + {NewRec NewState placedMines KindFire|NewState.placedMines} + [] (drone(Position)|T1)#drone then + ID=State.id KindFire=drone(Position) + {Send HumanPlayerGUI_Port drone(ID KindFire)} + {NewRec State chargedItems {List.subtract State.chargedItems KindFire}} + [] (sonar|T1)#sonar then + ID=State.id KindFire=sonar + {Send HumanPlayerGUI_Port sonar(ID)} + {NewRec State chargedItems {List.subtract State.chargedItems KindFire}} + + else + Search = {SearchForItem State.chargedItems Var} + case Search + of nil then + ID=State.id + KindFire=null + State + else + ID=State.id + KindFire=Search + State + + end + end + end + end + + fun {GetRandomElement L} + Idx=({OS.rand} mod {List.length L}) + 1 + in + {List.nth L Idx} + end + + fun{HandleFireMine State fireMine(ID Mine)} + PossibleMines={List.filter State.placedMines fun{$ mine(Position)} {ManhattanDistance State.pos Position} >= 2 end} + in + case PossibleMines + of nil then + ID=State.id + Mine=null + State + elseif {OS.rand} mod 3 \= 0 then MineToExplode={GetRandomElement PossibleMines} in + ID=State.id + Mine=MineToExplode.1 + case Mine + of pt(x:_ y:_) then + {Send HumanPlayerGUI_Port removeMine(ID Mine)} + end + {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) + {Send HumanPlayerGUI_Port lifeUpdate(State.id NewLife)} + {NewRec State life 0} + else + Msg=sayDamageTaken(State.id Damage NewLife) + {Send HumanPlayerGUI_Port lifeUpdate(State.id 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 nil|T then skip + [] initPosition(ID Pos)|T then NewState in + {Send HumanPlayerGUI_Port buildWindow} + {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 Direction)|T then NewState in %% Ignored + {System.show 'Player'#State.id.id#'received'#sayMove(ID Direction)} + {AliveTreatStream T State} + [] isDead(Answer)|T then + {System.show 'Player'#State.id.id#'received'#isDead(Answer)} + Answer=false + {System.show 'Player'#State.id.id#'replied'#isDead(Answer)} + {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 + 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 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 NewState RemovedDeadEnemy in %% 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:player020human) + life:Input.maxDamage + pos:pt(x:0 y:0) + chargingItems:[ {GetNewChargeFireItemRandom mine} {GetNewChargeFireItemRandom missile} + {GetNewChargeFireItemRandom sonar} {GetNewChargeFireItemRandom drone}] + chargedItems:nil + placedMines:nil + targets:nil + history:nil)} + end + Port + end +end \ No newline at end of file diff --git a/Player020Human.ozf b/Player020Human.ozf new file mode 100644 index 0000000000000000000000000000000000000000..49c21d6cece544e2713a28cc3ce087a5b9bef651 Binary files /dev/null and b/Player020Human.ozf differ diff --git a/Player020Random.ozf b/Player020Random.ozf new file mode 100644 index 0000000000000000000000000000000000000000..0423ae563442c8f6baf1ada35e9086893c01557e Binary files /dev/null and b/Player020Random.ozf differ diff --git a/Player069Rocketman.ozf b/Player069Rocketman.ozf deleted file mode 100644 index 672ecc8cea0f968c2b17b755d28f09a0ea41a893..0000000000000000000000000000000000000000 Binary files a/Player069Rocketman.ozf and /dev/null differ diff --git a/PlayerManager.oz b/PlayerManager.oz index 65887e581748e172358d4b42952aea1f6d148544..7a8cd28cc4684834d8c906fc87bb14193c1ec965 100644 --- a/PlayerManager.oz +++ b/PlayerManager.oz @@ -6,6 +6,7 @@ import Player014WellerMine Player020HiderAndSeeker Player020Random + Player020Human Player038Cartographer Player069Rocketman export @@ -31,6 +32,8 @@ in {Player038Cartographer.portPlayer Color ID} [] player069rocketman then {Player069Rocketman.portPlayer Color ID} + [] player020human then + {Player020Human.portPlayer Color ID} end end end \ No newline at end of file diff --git a/PlayerManager.ozf b/PlayerManager.ozf new file mode 100644 index 0000000000000000000000000000000000000000..642aca606b92fb9c70be4bc732192bfa65638be6 Binary files /dev/null and b/PlayerManager.ozf differ