-
Notifications
You must be signed in to change notification settings - Fork 0
/
TreasureGame_BT.elm
100 lines (84 loc) · 2.8 KB
/
TreasureGame_BT.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
module TreasureGame_BT exposing (..)
import Grid exposing (screen2grid)
import BehaviourTree exposing (..)
import TreasureGame exposing (Explorer, Dungeon, dungeon0, Prop(Chest),
isKey, isLockedDoor, initDungeon, runDungeon, drawDungeon)
import PathFollowing exposing (Exploration(..), explore)
import Collage exposing (Form, text, move)
import Text
import Time exposing (Time, inSeconds)
import Random exposing (Generator)
import Color exposing (purple)
--- STRUCTURES ---
type alias Simulation = (Dungeon, Behaviour Dungeon)
sim0 : Simulation
sim0 = (dungeon0, BehaviourTree.empty)
--- BEHAVIOR ---
seekKey : Routine Dungeon
seekKey dungeon = let
e = dungeon.explorer
grid = dungeon.floor
start = screen2grid e.pos dungeon.floor
keys = List.filter (fst >> isKey) dungeon.loot
in
case keys of
[] -> ({ dungeon | explorer = { e | state = Resting } }, Failure)
(_, target) :: _ -> case dungeon.explorer.state of
Resting ->
({ dungeon | explorer = { e | state = Plotting target } }, Success)
_ -> (dungeon, Running)
seekDoor : Routine Dungeon
seekDoor dungeon = let
e = dungeon.explorer
grid = dungeon.floor
start = screen2grid e.pos dungeon.floor
lockedDoors = List.filter (fst >> isLockedDoor) dungeon.loot
in
case lockedDoors of
[] -> ({ dungeon | explorer = { e | state = Resting } }, Failure)
(_, target) :: _ -> case dungeon.explorer.state of
Resting ->
({ dungeon | explorer = { e | state = Plotting target } }, Success)
_ -> (dungeon, Running)
seekTreasure : Routine Dungeon
seekTreasure dungeon = let
e = dungeon.explorer
grid = dungeon.floor
start = screen2grid e.pos dungeon.floor
chests = List.filter (fst >> (==) Chest) dungeon.loot
in
case chests of
(_, target) :: _ -> case dungeon.explorer.state of
Resting ->
({ dungeon | explorer = { e | state = Plotting target } }, Running)
_ -> (dungeon, Running)
[] -> (dungeon, Success)
initTree : Behaviour Dungeon
initTree = Sequence
[ repeat (Leaf seekKey)
, repeat (Leaf seekDoor)
, Leaf seekTreasure
]
--- SIMULATION ---
initSim : Generator Simulation
initSim = Random.map (\dungeon -> (dungeon, initTree)) initDungeon
simulate : Time -> Simulation -> Simulation
simulate t (dungeon, tree) = let
(new_dungeon, _, new_tree) = BehaviourTree.step tree (runDungeon t dungeon)
in
(new_dungeon, new_tree)
--- DRAWING ---
stateName : Behaviour Dungeon -> String
stateName tree = case tree of
Sequence bb -> case List.length bb of
3 -> "Seek Keys"
2 -> "Seek Doors"
1 -> "Seek Treasure"
0 -> "Celebrate !!"
_ -> ""
_ -> ""
drawSim : Simulation -> List Form
drawSim (dungeon, tree) = drawDungeon dungeon
++ [stateName tree |> Text.fromString
|> Text.color purple |> Text.height 18 |> Text.bold
|> text |> move dungeon.explorer.pos]