diff --git a/client/src/components/LeftPanel.tsx b/client/src/components/LeftPanel.tsx
index 1e2fc88..0e75963 100644
--- a/client/src/components/LeftPanel.tsx
+++ b/client/src/components/LeftPanel.tsx
@@ -1,110 +1,25 @@
import * as React from 'react';
import { useState, useEffect } from 'react';
-import ReactMarkdown from 'react-markdown';
import './inventory.css'
-
-import { Paper, Box, Typography, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab, Divider, Button, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLock, faLockOpen, faBook, faHammer, faBan } from '@fortawesome/free-solid-svg-icons'
import Markdown from './Markdown';
-function TacticDoc(props) {
- return (
-
- }>
- {props.tactic.name}
-
-
- {props.tactic.content}
-
- )
-}
-
-function LemmaDoc({ lemma }) {
- return (
-
- }>
- {lemma.userName}
-
-
- {lemma.content}
-
- )
-}
-
-function LemmaDocs({ lemmas }) {
- const [categories, setCategories] = useState(new Map())
- const [curCategory, setCurCategory] = useState("")
-
- const changeTab = (event: React.SyntheticEvent, newValue : string) => {
- setCurCategory(newValue);
- };
-
- useEffect(() => {
- const cats = new Map()
- lemmas.forEach(function (item) {
- const category = item.category
- cats.set(category, (cats.get(category) || []).concat([item]))
- });
- setCategories(cats)
- setCurCategory(cats.keys().next().value)
- }, [lemmas]);
-
- return (
-
-
-
- {(Array.from(categories)).map(([category, _]) => )}
-
-
- {curCategory && categories.get(curCategory).map((lemma) => )}
-
)
-}
-function LeftPanel({ spells, inventory, showSidePanel, setShowSidePanel }) {
+function LeftPanel({ tactics, inventory, showSidePanel, setShowSidePanel }) {
return (
<>
- { ["rfl", "tauto", "trivial", "simp", "left", "right", "assumption", "constructor"].map ((tac) => {
- const locked = Math.random() > 0.5
- const disabled = Math.random() > 0.5
- const icon = locked ? faLock : disabled ? faBan : faLockOpen
+ { tactics.map (({name, locked, disabled}) => {
+ const icon = locked ?
:
+ disabled ?
: ""
const className = locked ? "locked" : disabled ? "disabled" : ""
- return
{tac}
+ return
{icon} {name}
})}
+ {/* TODO: Click on Tactic: show info
+ TODO: click on paste icon -> paste into command line */}
-
-
- setShowSidePanel(true)}>
-
-
-
-
-
- {spells && spells.length > 0 &&
-
- {spells.map((spell) => )}
- }
-
-
-
-
-
-
-
-
- {inventory && inventory.length > 0 &&
-
-
- }
-
-
>
)
}
diff --git a/client/src/components/Level.tsx b/client/src/components/Level.tsx
index 8743d72..77134bc 100644
--- a/client/src/components/Level.tsx
+++ b/client/src/components/Level.tsx
@@ -184,8 +184,8 @@ function Level() {
-
+ {!level.isLoading && }
>
diff --git a/client/src/components/inventory.css b/client/src/components/inventory.css
index 5b04633..40f98c1 100644
--- a/client/src/components/inventory.css
+++ b/client/src/components/inventory.css
@@ -2,6 +2,7 @@
display: flex;
gap: .5em;
flex-wrap : wrap;
+ padding: 1em
}
.tactic-inventory .tactic {
diff --git a/client/src/state/api.ts b/client/src/state/api.ts
index 082fe53..23e3de1 100644
--- a/client/src/state/api.ts
+++ b/client/src/state/api.ts
@@ -14,7 +14,7 @@ interface LevelInfo {
title: null|string,
introduction: null|string,
index: number,
- tactics: any[],
+ tactics: {name: string, disabled: boolean, locked: boolean}[],
lemmas: any[],
descrText: null|string,
descrFormat: null|string,
diff --git a/server/leanserver/GameServer/Commands.lean b/server/leanserver/GameServer/Commands.lean
index 231a9a9..d0174dc 100644
--- a/server/leanserver/GameServer/Commands.lean
+++ b/server/leanserver/GameServer/Commands.lean
@@ -266,28 +266,41 @@ elab "MakeGame" : command => do
-- Compute which tactics are available in which level:
let mut newTacticsInWorld : HashMap Name (HashSet Name) := {}
+ let mut allTactics : HashSet Name := {}
for (worldId, world) in game.worlds.nodes.toArray do
let mut newTactics : HashSet Name:= {}
for (_, level) in world.levels.toArray do
newTactics := newTactics.insertMany level.newTactics
+ allTactics := allTactics.insertMany level.newTactics
newTacticsInWorld := newTacticsInWorld.insert worldId newTactics
- let mut tacticsInWorld : HashMap Name (HashSet Name) := {}
+ let tacticAvailability₀ : HashMap Name TacticAvailability :=
+ HashMap.ofList $
+ allTactics.toList.map fun name =>
+ (name, {name, locked := true, disabled := false})
+
+ let mut tacticsInWorld : HashMap Name (HashMap Name TacticAvailability) := {}
for (worldId, _) in game.worlds.nodes.toArray do
- let mut tactics : HashSet Name:= {}
+ let mut tactics : HashMap Name TacticAvailability := tacticAvailability₀
let predecessors := game.worlds.predecessors worldId
for predWorldId in predecessors do
- tactics := tactics.insertMany (newTacticsInWorld.find! predWorldId)
+ for tac in newTacticsInWorld.find! predWorldId do
+ tactics := tactics.insert tac {name := tac, locked := false, disabled := false}
tacticsInWorld := tacticsInWorld.insert worldId tactics
for (worldId, world) in game.worlds.nodes.toArray do
let mut tactics := tacticsInWorld.find! worldId
- logInfo m!"{tactics.toArray}"
let levels := world.levels.toArray.insertionSort fun a b => a.1 < b.1
for (levelId, level) in levels do
- tactics := tactics.insertMany level.newTactics
-
+ for tac in level.newTactics do
+ tactics := tactics.insert tac {name := tac, locked := false, disabled := false}
+ for tac in level.disabledTactics do
+ tactics := tactics.insert tac {name := tac, locked := false, disabled := true}
+
+ let tacticArray := tactics.toArray
+ |>.insertionSort (fun a b => a.1.toString < b.1.toString)
+ |>.map (·.2)
modifyLevel ⟨← getCurGameId, worldId, levelId⟩ fun level => do
- return {level with tactics := ← tactics.toArray.mapM getTacticDoc!}
+ return {level with tactics := tacticArray}
diff --git a/server/leanserver/GameServer/EnvExtensions.lean b/server/leanserver/GameServer/EnvExtensions.lean
index 6e726f5..9b5aa67 100644
--- a/server/leanserver/GameServer/EnvExtensions.lean
+++ b/server/leanserver/GameServer/EnvExtensions.lean
@@ -144,6 +144,12 @@ structure LevelId where
level : Nat
deriving Inhabited
+structure TacticAvailability where
+ name : Name
+ locked : Bool
+ disabled : Bool
+deriving ToJson, FromJson, Repr
+
def getCurLevelId [MonadError m] : m LevelId := do
return { game := ← getCurGameId, world := ← getCurWorldId, level := ← getCurLevelIdx}
@@ -170,7 +176,7 @@ structure GameLevel where
-- only these tactics are allowed in this level (ignore if empty):
onlyTactics: Array Name := default
-- tactics in this level (computed by `MakeGame`):
- tactics: Array TacticDocEntry := default
+ tactics: Array TacticAvailability := default
-- new lemmas introduces by this level:
newLemmas: Array Name := default
-- lemmas exceptionally forbidden in this level:
diff --git a/server/leanserver/GameServer/Game.lean b/server/leanserver/GameServer/Game.lean
index cea1e91..9959d48 100644
--- a/server/leanserver/GameServer/Game.lean
+++ b/server/leanserver/GameServer/Game.lean
@@ -41,7 +41,7 @@ Fields:
structure LevelInfo where
index : Nat
title : String
- tactics: Array TacticDocEntry
+ tactics: Array TacticAvailability
lemmas: Array LemmaDocEntry
introduction : String
descrText : String := ""