diff --git a/GUI.oz b/GUI.oz new file mode 100644 index 0000000000000000000000000000000000000000..7f69fc3b8186ae92aac9584b36407f8076b1faff --- /dev/null +++ b/GUI.oz @@ -0,0 +1,286 @@ +functor +import + QTk at 'x-oz://system/wp/QTk.ozf' + Input +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(Toolbar Desc DescScore)} + + {Window show} + + % configure rows and set headers + {Grid rowconfigure(1 minsize:50 weight:0 pad:5)} + for N in 1..NRow do + {Grid rowconfigure(N+1 minsize:50 weight:0 pad:5)} + {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:5)} + for N in 1..NColumn do + {Grid columnconfigure(N+1 minsize:50 weight:0 pad:5)} + {Grid configure({Label N} row:1 column:N+1 sticky:wesn)} + end + % configure scoreboard + {GridScore rowconfigure(1 minsize:50 weight:0 pad:5)} + for N in 1..(Input.nbPlayer) do + {GridScore columnconfigure(N minsize:50 weight:0 pad:5)} + 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:5) + 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:5 relief:raised bg:Color ipadx:5 ipady:5) + LabelScore = label(text:Input.maxDamage borderwidth:5 handle:HandleScore relief:solid bg:Color ipadx:5 ipady:5) + 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:5 ipady:5) + {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.1 == Position) then + {RemoveItem Grid H.2} + 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 + {HandleScore set(0)} + if (ID == WantedID) then + 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 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}}} + {TreatStream T Grid State} + [] 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/Input.oz b/Input.oz new file mode 100644 index 0000000000000000000000000000000000000000..3e676eb883e5e0b8e3cd40c97753821ef3ff9db8 --- /dev/null +++ b/Input.oz @@ -0,0 +1,93 @@ +functor +export + isTurnByTurn:IsTurnByTurn + nRow:NRow + nColumn:NColumn + map:Map + nbPlayer:NbPlayer + players:Players + colors:Colors + thinkMin:ThinkMin + thinkMax:ThinkMax + turnSurface:TurnSurface + maxDamage:MaxDamage + missile:Missile + mine:Mine + sonar:Sonar + drone:Drone + minDistanceMine:MinDistanceMine + maxDistanceMine:MaxDistanceMine + minDistanceMissile:MinDistanceMissile + maxDistanceMissile:MaxDistanceMissile + guiDelay:GUIDelay +define + IsTurnByTurn + NRow + NColumn + Map + NbPlayer + Players + Colors + ThinkMin + ThinkMax + TurnSurface + MaxDamage + Missile + Mine + Sonar + Drone + MinDistanceMine + MaxDistanceMine + MinDistanceMissile + MaxDistanceMissile + GUIDelay +in + + +%%%% Style of game %%%% + + IsTurnByTurn = true + +%%%% 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 1 1 0 0 0 0 0] + [0 0 1 1 0 0 1 0 0 0] + [0 0 0 0 0 0 0 0 0 0]] + +%%%% Players description %%%% + + NbPlayers = 2 + Players = [player1 player2] + Colors = [red blue] + +%%%% Surface time/turns %%%% + + TurnSurface = 3 + +%%%% Life %%%% + + MaxDamage = 4 + +%%%% Number of load for each item %%%% + + Missile = 3 + Mine = 3 + Sonar = 3 + Drone = 3 + +%%%% Distances of placement %%%% + + MinDistanceMine = 1 + MaxDistanceMine = 2 + MinDistanceMissile = 1 + MaxDistanceMissile = 4 + +%%%% Waiting time for the GUI between each effect %%%% + + GUIDelay = 500 % ms + +end \ No newline at end of file diff --git a/Main.oz b/Main.oz new file mode 100644 index 0000000000000000000000000000000000000000..fb4345580a2a583cebf4b6fb293a43c89a568b5f --- /dev/null +++ b/Main.oz @@ -0,0 +1,18 @@ +functor +import + GUI + Input + PlayerManager +define + %% TODO +in + %% 1. Create the port for the GUI and launch its interface + %% 2. Create the port for every player using the PlayerManager. + %% 3. Choose its initial point for every player. + %% 4. Choose game mode and launch the game. + + %% TODO: implement the controllers: + %% - Turn-by-turn + %% - Simultaneous + +end \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f562d291fe324d9a42c1d48cf0a4be2677e52496 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +# ---------------------------- +# group nb XXX +# noma1 : name1 surname1 +# noma2 : name2 surname2 +# ---------------------------- + +# TODO complete the header with your group number, your noma's and full names + +# TODO write your makefile here \ No newline at end of file diff --git a/Player000Basic.oz b/Player000Basic.oz new file mode 100644 index 0000000000000000000000000000000000000000..b286e892036a2ee2f2aec9ff4ea4d17c085a563a --- /dev/null +++ b/Player000Basic.oz @@ -0,0 +1,24 @@ +functor +import +Input +export + portPlayer:StartPlayer +define + StartPlayer + TreatStream +in + fun{StartPlayer Color ID} + Stream + Port + in + {NewPort Stream Port} + thread + {TreatStream Stream} + end + Port + end + + proc{TreatStream Stream} %% TODO: you may add as many argument as needed + %% TODO: complete + end +end \ No newline at end of file diff --git a/PlayerManager.oz b/PlayerManager.oz new file mode 100644 index 0000000000000000000000000000000000000000..43be76d3c4974544799b9498b43c9199cc883134 --- /dev/null +++ b/PlayerManager.oz @@ -0,0 +1,16 @@ +functor +import + Player000Basic + ... +export + playerGenerator:PlayerGenerator +define + PlayerGenerator +in + fun{PlayerGenerator Kind Color ID} + case Kind + of player000basic then {Player000basic.portPlayer Color ID} + ... + end + end +end \ No newline at end of file diff --git a/statement.pdf b/statement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..64f699deeb8c23e5c75dc5aac8dc26a7d9b5e51f Binary files /dev/null and b/statement.pdf differ