@@ -0,0 +1,222 @@ | |||
from memory_Context import * | |||
from llm import * | |||
# Exit | |||
# | |||
# Conditions: | |||
# 1. `e`, `exit`, `q`, or `quit` was entered | |||
# 2. Victory has just been reported | |||
@llm_by_value | |||
def cli_exit( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "input" and | |||
( | |||
c.input == "e" or | |||
c.input == "exit" or | |||
c.input == "q" or | |||
c.input == "quit" | |||
) | |||
): | |||
c.exit = True | |||
c.recentField = "exit" | |||
return c | |||
#} | |||
if ( | |||
c.recentField == "outputVictory" | |||
): | |||
c.exit = True | |||
c.recentField = "exit" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Ask user to go on | |||
# | |||
# Conditions: | |||
# 1. Items have just matched and there are still items left to select | |||
@llm_by_value | |||
def cli_goOn( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "outputMatchedItems" and | |||
len(c.hiddenItems) != len(c.playfieldItems) | |||
): | |||
c.outputGoOn = "Go on:" | |||
c.recentField = "outputGoOn" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Greet the user | |||
# | |||
# Conditions: | |||
# 1. Just launched | |||
@llm_by_value | |||
def cli_greetUser( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "didLaunch" and | |||
c.didLaunch == True | |||
): | |||
c.outputGreeting = "OGS Memory Command Line Interface" | |||
c.recentField = "outputGreeting" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Ask user to select second item to have a pair of selected items | |||
# | |||
# Conditions: | |||
# 1. Single item has just been selected | |||
@llm_by_value | |||
def cli_promptSecondItemSelection( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 | |||
): | |||
c.outputPromptSelection = "Select the second item now:" | |||
c.recentField = "outputPromptSelection" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report matched items | |||
# | |||
# Conditions: | |||
# 1. Items were hidden (i.e., they matched) | |||
@llm_by_value | |||
def cli_reportMatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "hiddenItems" | |||
): | |||
c.outputMatchedItems = "Items matched!" | |||
c.recentField = "outputMatchedItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report victory | |||
@llm_by_value | |||
def cli_reportVictory( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "victory" | |||
): | |||
c.outputVictory = "VICTORY! The game is over now" | |||
c.recentField = "outputVictory" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Select item | |||
# | |||
# Conditions: | |||
# 1. Id is digit | |||
@llm_by_value | |||
def cli_selectItem( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "input" and | |||
llm_isDigit(c.input) | |||
): | |||
# CLI ids start with 1 while memory module has ids starting with 0 | |||
# Convert CLI id to memory id | |||
c.selectedId = llm_strToInt(c.input) - 1 | |||
c.recentField = "selectedId" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Show help (aka commands) | |||
# | |||
# Conditions: | |||
# 1. Just launched | |||
# 1. `h` or `help` was entered | |||
@llm_by_value | |||
def cli_showHelp( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
( | |||
c.recentField == "didLaunch" and | |||
c.didLaunch == True | |||
) or | |||
( | |||
c.recentField == "input" and | |||
c.input == "h" | |||
) or | |||
( | |||
c.recentField == "input" and | |||
c.input == "help" | |||
) | |||
): | |||
c.outputHelp = "Commands:\n\te, exit, q, quit\n\t\tExit\n\th, help\n\t\tList commands\n\t1, 2, 3, ...\n\t\tSelect item\nEnter your choice:" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report mismatched items | |||
@llm_by_value | |||
def cli_reportMismatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "mismatchedItems" | |||
): | |||
c.outputMismatchedItems = "Wrong! Try again:" | |||
c.recentField = "outputMismatchedItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
## Report selection of invalid item ids | |||
## | |||
## Conditions: | |||
## 1. Index out of bounds: less than minimum | |||
## 2. Index out of bounds: greater than maximum | |||
## 3. Item is already hidden | |||
##@llm_by_value | |||
##def cli_shouldReportInvalidItemSelection( | |||
## c: cli_Context | |||
##) -> cli_Context: | |||
## if ( | |||
## c.recentField == "cMemory" and | |||
## c.cMemory.recentField == "selectedItems" and | |||
## len(c.cMemory.selectedItems) == 1 | |||
## ): | |||
## c.outputPromptSelection = "Select the second item now:" | |||
## c.recentField = "outputPromptSelection" | |||
## return c | |||
## #} | |||
## c.recentField = "none" | |||
## return c | |||
###} |
@@ -0,0 +1,303 @@ | |||
from cli import * | |||
from memory import * | |||
from memory_Context import * | |||
def cli_test_exit_e( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "e" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_e" | |||
#} | |||
return "ERR: cli_exit_e" | |||
#} | |||
def cli_test_exit_exit( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "exit" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_exit" | |||
#} | |||
return "ERR: cli_exit_e" | |||
#} | |||
def cli_test_exit_victory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of tiles. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
# Match the second pair of tiles. | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "4" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = memory_detectVictory(c) | |||
c = cli_reportVictory(c) | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_victory" | |||
#} | |||
return "ERR: cli_exit_victory" | |||
#} | |||
def cli_test_exit_q( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "q" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_q" | |||
#} | |||
return "ERR: cli_exit_q" | |||
#} | |||
def cli_test_exit_quit( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "quit" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_quit" | |||
#} | |||
return "ERR: cli_exit_quit" | |||
#} | |||
def cli_test_goOn( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of items. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = cli_reportMatchedItems(c) | |||
c = cli_goOn(c) | |||
if ( | |||
c.recentField == "outputGoOn" | |||
): | |||
return "OK: cli_goOn" | |||
#} | |||
return "ERR: cli_goOn" | |||
#} | |||
def cli_test_greetUser( | |||
) -> str: | |||
c = memory_createContext() | |||
c.didLaunch = True | |||
c.recentField = "didLaunch" | |||
c = cli_greetUser(c) | |||
if ( | |||
c.recentField == "outputGreeting" | |||
): | |||
return "OK: cli_greetUser" | |||
#} | |||
return "ERR: cli_greetUser" | |||
#} | |||
def cli_test_promptSecondItemSelection( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = cli_promptSecondItemSelection(c) | |||
if ( | |||
c.recentField == "outputPromptSelection" | |||
): | |||
return "OK: cli_promptSecondItemSelection" | |||
#} | |||
return "ERR: cli_promptSecondItemSelection" | |||
#} | |||
def cli_test_reportMatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = cli_reportMatchedItems(c) | |||
if ( | |||
c.recentField == "outputMatchedItems" | |||
): | |||
return "OK: cli_reportMatchedItems" | |||
#} | |||
return "ERR: cli_reportMatchedItems" | |||
#} | |||
def cli_test_reportMismatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_detectMismatchedItems(c) | |||
c = cli_reportMismatchedItems(c) | |||
if ( | |||
c.recentField == "outputMismatchedItems" | |||
): | |||
return "OK: cli_reportMismatchedItems" | |||
#} | |||
return "ERR: cli_reportMismatchedItems" | |||
#} | |||
def cli_test_selectItem( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
if ( | |||
c.recentField == "selectedId" and | |||
c.selectedId == 0 | |||
): | |||
return "OK: cli_selectItem" | |||
#} | |||
return "ERR: cli_selectItem" | |||
#} | |||
def cli_test_showHelp_h( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "h" | |||
c.recentField = "input" | |||
c = cli_showHelp(c) | |||
if ( | |||
c.recentField == "outputHelp" | |||
): | |||
return "OK: cli_showHelp_h" | |||
#} | |||
return "ERR: cli_showHelp_h" | |||
#} | |||
def cli_test_showHelp_help( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "help" | |||
c.recentField = "input" | |||
c = cli_showHelp(c) | |||
if ( | |||
c.recentField == "outputHelp" | |||
): | |||
return "OK: cli_showHelp_help" | |||
#} | |||
return "ERR: cli_showHelp_help" | |||
#} | |||
def cli_test_reportVictory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of tiles. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
# Match the second pair of tiles. | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "4" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = memory_detectVictory(c) | |||
c = cli_reportVictory(c) | |||
if ( | |||
c.recentField == "outputVictory" | |||
): | |||
return "OK: cli_reportVictory" | |||
#} | |||
return "ERR: cli_reportVictory" | |||
#} | |||
#def cli_test_shouldReportIvalidItemSelection_outOfBoundsMin( | |||
#) -> str: | |||
# c = cli_createContext() | |||
# c.cMemory = memory_createContext() | |||
# c.input = "0" | |||
# c = cli_selectItem(c) | |||
# c = cli_shouldReportInvalidItemSelection(c) | |||
# if ( | |||
# c.recentField == "outputInvalidItemSelection" | |||
# ): | |||
# return "OK: cli_shouldReportInvalidItemSelection" | |||
# #} | |||
# return "ERR: cli_shouldReportInvalidItemSelection" | |||
##} | |||
# |
@@ -0,0 +1,53 @@ | |||
import copy | |||
class ctx_Controller: | |||
def __init__(self, c): | |||
self.callbacks = [] | |||
self.context = c | |||
self.functions = [] | |||
self.isProcessingQueue = False | |||
self.queue = [] | |||
def executeFunctions(self): | |||
c = self.queue.pop(0) | |||
for f in self.functions: | |||
ctx = f(c) | |||
if ctx.recentField != "none": | |||
self.queue.append(ctx) | |||
self.context.recentField = c.recentField | |||
self.context.setField(c.recentField, c.field(c.recentField)) | |||
self.reportContext() | |||
def processQueue(self): | |||
# Decline recursion. | |||
if self.isProcessingQueue: | |||
return | |||
self.isProcessingQueue = True | |||
while len(self.queue) > 0: | |||
self.executeFunctions() | |||
self.isProcessingQueue = False | |||
def registerCallback(self, cb): | |||
self.callbacks.append(cb) | |||
def registerFieldCallback(self, fieldName, cb): | |||
self.callbacks.append(lambda c: cb(c) if c.recentField == fieldName else None) | |||
def registerFunction(self, f): | |||
self.functions.append(f) | |||
def registerFunctions(self, funcs): | |||
for f in funcs: | |||
self.functions.append(f) | |||
def reportContext(self): | |||
for cb in self.callbacks: | |||
cb(self.context) | |||
def set(self, fieldName, value): | |||
c = copy.deepcopy(self.context) | |||
c.setField(fieldName, value) | |||
c.recentField = fieldName | |||
self.queue.append(c) | |||
self.processQueue() |
@@ -0,0 +1,142 @@ | |||
from ctx import * | |||
from memory import * | |||
from memory_Context import * | |||
def ctx_test_Controller_executeFunctions_registerFunction_set( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
# Disable automatic invocation of executeFunctions. | |||
ctrl.isProcessingQueue = True | |||
ctrl.set("input", "123") | |||
@llm_by_value | |||
def processInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
c.outputHelp = "Checked" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
ctrl.registerFunction(processInput) | |||
# Apply 'input'. | |||
ctrl.executeFunctions() | |||
# Apply 'outputHelp'. | |||
ctrl.executeFunctions() | |||
if ( | |||
c.input == "123" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_executeFunctions_set" | |||
#} | |||
return "ERR: ctx_Controller_executeFunctions_set" | |||
#} | |||
def ctx_test_Controller_processQueue( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
@llm_by_value | |||
def processInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
c.outputHelp = "Checked" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
ctrl.registerFunction(processInput) | |||
ctrl.set("input", "abc"); | |||
if ( | |||
c.input == "abc" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_processQueue" | |||
#} | |||
return "ERR: ctx_Controller_processQueue" | |||
#} | |||
def ctx_test_Controller_registerFieldCallback_match( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.recentField = "input" | |||
globals()["callbackInput"] = "" | |||
def setCallbackInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
globals()["callbackInput"] = c.input | |||
ctrl.registerFieldCallback("input", setCallbackInput) | |||
ctrl.reportContext() | |||
if ( | |||
c.input == globals()["callbackInput"] | |||
): | |||
return "OK: ctx_Controller_registerFieldCallback_match" | |||
#} | |||
return "ERR: ctx_Controller_registerFieldCallback_match" | |||
#} | |||
def ctx_test_Controller_registerFieldCallback_mismatch( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.outputHelp = "you" | |||
# A field other than 'input' is marked recent. | |||
c.recentField = "outputHelp" | |||
globals()["callbackInput"] = "" | |||
def setCallbackInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
globals()["callbackInput"] = c.input | |||
ctrl.registerFieldCallback("input", setCallbackInput) | |||
ctrl.reportContext() | |||
if ( | |||
globals()["callbackInput"] == "" | |||
): | |||
return "OK: ctx_Controller_registerFieldCallback_mismatch" | |||
#} | |||
return "ERR: ctx_Controller_registerFieldCallback_mismatch" | |||
#} | |||
def ctx_test_memoryContext_field( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
if ( | |||
c.field("input") == "abc" | |||
): | |||
return "OK: ctx_memoryContext_field" | |||
#} | |||
return "ERR: ctx_memoryContext_field" | |||
#} | |||
def ctx_test_memoryContext_setField( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
c.setField("input", "123") | |||
if ( | |||
c.input == "123" | |||
): | |||
return "OK: ctx_memoryContext_setField" | |||
#} | |||
return "ERR: ctx_memoryContext_setField" | |||
#} |
@@ -0,0 +1,317 @@ | |||
import arcade | |||
from gui_aux import * | |||
from desktop_Platform import * | |||
def desktop_createDesc(p): | |||
p.desc = arcade.Sprite() | |||
p.descSprites.append(p.desc) | |||
p.desc.texture = p.descTextures[0] | |||
# Position. | |||
pos = gui_aux_cellScreenPosition(p.c, p.c.descPosition) | |||
p.desc.left = pos[0] | |||
p.desc.top = pos[1] | |||
# Invisible by default. | |||
p.desc.visible = False | |||
#} | |||
def desktop_createDeselectedTiles(p): | |||
for (id, pos) in enumerate(p.c.tilePositions): | |||
tile = arcade.AnimatedTimeBasedSprite() | |||
p.deselectedTiles.append(tile) | |||
p.deselectedSprites.append(tile) | |||
tile.guid = id | |||
tile.texture = p.textures[0] | |||
# Animation between two textures. | |||
a1 = arcade.sprite.AnimationKeyframe(0, 700, p.textures[0]) | |||
a2 = arcade.sprite.AnimationKeyframe(1, 700, p.textures[1]) | |||
tile.frames.append(a1) | |||
tile.frames.append(a2) | |||
# Position. | |||
tile.left = pos[0] | |||
tile.top = pos[1] | |||
#} | |||
#} | |||
def desktop_createSelectedTiles(p): | |||
for (id, pos) in enumerate(p.c.tilePositions): | |||
tile = arcade.Sprite() | |||
p.selectedTiles.append(tile) | |||
p.selectedSprites.append(tile) | |||
tile.guid = id | |||
tile.texture = p.textures[2 + p.c.playfieldItems[id]] | |||
# Position. | |||
tile.left = pos[0] | |||
tile.top = pos[1] | |||
# Invisible by default. | |||
tile.visible = False | |||
#} | |||
#} | |||
def desktop_createSplash(p): | |||
p.splash = arcade.Sprite() | |||
p.splashSprites.append(p.splash) | |||
p.splash.texture = p.splashTextures[0] | |||
# Position. | |||
pos = gui_aux_cellScreenPosition(p.c, [0, 0]) | |||
p.splash.left = pos[0] | |||
p.splash.top = pos[1] | |||
#} | |||
def desktop_createTitle(p): | |||
p.title = arcade.Sprite() | |||
p.titleSprites.append(p.title) | |||
p.title.texture = p.titleTextures[0] | |||
# Position. | |||
pos = gui_aux_cellScreenPosition(p.c, p.c.titlePosition) | |||
p.title.left = pos[0] | |||
p.title.top = pos[1] | |||
# Invisible by default. | |||
p.title.visible = False | |||
#} | |||
# Deselect mismatched tiles | |||
# | |||
# Conditions: | |||
# 1. Time to deselect mismatched items | |||
def desktop_deselectMismatchedTiles(p): | |||
if ( | |||
p.c.recentField == "deselectMismatchedTiles" | |||
): | |||
for id in p.c.mismatchedItems: | |||
p.deselectedTiles[id].visible = True | |||
p.selectedTiles[id].visible = False | |||
#} | |||
#} | |||
#} | |||
# Display description for the first selected tile | |||
# | |||
# Conditions: | |||
# 1. tile has just been selected and it's the first one in pair | |||
def desktop_displayDesc(p): | |||
if ( | |||
p.c.recentField == "selectedId" and | |||
( | |||
len(p.c.selectedItems) == 0 or | |||
len(p.c.selectedItems) == 2 | |||
) | |||
): | |||
gid = p.c.playfieldItems[p.c.selectedId] | |||
p.desc.texture = p.descTextures[gid] | |||
p.desc.visible = True | |||
#} | |||
#} | |||
# Display ending splash screen | |||
# | |||
# Conditions: | |||
# 1. Time to display victory screen | |||
def desktop_displayEndingSplashScreen(p): | |||
if ( | |||
p.c.recentField == "displayEndingSplashScreen" | |||
): | |||
p.splash.texture = p.splashTextures[1] | |||
p.splash.visible = True | |||
#} | |||
#} | |||
# Hide deselected tile and show selected one | |||
# | |||
# Conditions: | |||
# 1. tile has just been selected | |||
def desktop_displaySelectedTile(p): | |||
if ( | |||
p.c.recentField == "selectedId" | |||
): | |||
id = p.c.selectedId | |||
p.deselectedTiles[id].visible = False | |||
p.selectedTiles[id].visible = True | |||
#} | |||
#} | |||
# Display title for the first selected tile | |||
# | |||
# Conditions: | |||
# 1. tile has just been selected and it's the first one in pair | |||
def desktop_displayTitle(p): | |||
if ( | |||
p.c.recentField == "selectedId" and | |||
( | |||
len(p.c.selectedItems) == 0 or | |||
len(p.c.selectedItems) == 2 | |||
) | |||
): | |||
gid = p.c.playfieldItems[p.c.selectedId] | |||
p.title.texture = p.titleTextures[gid] | |||
p.title.visible = True | |||
#} | |||
#} | |||
# Hide beginning splash screen | |||
# | |||
# Conditions: | |||
# 1. Time to hide | |||
def desktop_hideBeginningSplashScreen(p): | |||
if ( | |||
p.c.recentField == "hideBeginningSplashScreen" | |||
): | |||
p.splash.visible = False | |||
#} | |||
#} | |||
# Hide description | |||
# | |||
# Conditions: | |||
# 1. tiles has been mismatched or timed out to to hide after matching | |||
def desktop_hideDesc(p): | |||
if ( | |||
p.c.recentField == "hideMatchingTiles" or | |||
p.c.recentField == "mismatchedItems" | |||
): | |||
p.desc.visible = False | |||
#} | |||
#} | |||
# Hide matching tiles | |||
# | |||
# Conditions: | |||
# 1. Time to hide matching items | |||
def desktop_hideMatchingTiles(p): | |||
if ( | |||
p.c.recentField == "hideMatchingTiles" | |||
): | |||
for id in p.c.selectedItems: | |||
p.deselectedTiles[id].visible = False | |||
p.selectedTiles[id].visible = False | |||
#} | |||
#} | |||
#} | |||
# Hide title | |||
# | |||
# Conditions: | |||
# 1. tiles has been mismatched or timed out to to hide after matching | |||
def desktop_hideTitle(p): | |||
if ( | |||
p.c.recentField == "hideMatchingTiles" or | |||
p.c.recentField == "mismatchedItems" | |||
): | |||
p.title.visible = False | |||
#} | |||
#} | |||
# Load description textures | |||
def desktop_loadDescTextures(p): | |||
texs = [] | |||
for (id, td) in enumerate(p.c.descTextureDescriptions): | |||
tex = arcade.load_texture( | |||
td.fileName, | |||
x = td.x, | |||
y = td.y, | |||
width = td.width, | |||
height = td.height | |||
) | |||
texs.append(tex) | |||
#} | |||
p.descTextures = texs | |||
#} | |||
# Load beginning and ending textures | |||
def desktop_loadSplashTextures(p): | |||
texs = [] | |||
for (id, td) in enumerate(p.c.splashTextureDescriptions): | |||
tex = arcade.load_texture( | |||
td.fileName, | |||
x = td.x, | |||
y = td.y, | |||
width = td.width, | |||
height = td.height | |||
) | |||
texs.append(tex) | |||
print(f"desktop_loadST: '{tex}'") | |||
#} | |||
p.splashTextures = texs | |||
#} | |||
# Load tile textures | |||
def desktop_loadTextures(p): | |||
texs = [] | |||
for (id, td) in enumerate(p.c.textureDescriptions): | |||
tex = arcade.load_texture( | |||
td.fileName, | |||
x = td.x, | |||
y = td.y, | |||
width = td.width, | |||
height = td.height | |||
) | |||
texs.append(tex) | |||
#} | |||
p.textures = texs | |||
#} | |||
# Load tiTLe textures | |||
def desktop_loadTitleTextures(p): | |||
texs = [] | |||
for (id, td) in enumerate(p.c.titleTextureDescriptions): | |||
tex = arcade.load_texture( | |||
td.fileName, | |||
x = td.x, | |||
y = td.y, | |||
width = td.width, | |||
height = td.height | |||
) | |||
texs.append(tex) | |||
#} | |||
p.titleTextures = texs | |||
#} | |||
# Postpone deselection of mismatched tiles for better UX | |||
# | |||
# Conditions: | |||
# 1. a pair of tiles has been mismatched | |||
def desktop_scheduleDeselectionOfMismatchedTiles(p): | |||
if ( | |||
p.c.recentField == "mismatchedItems" | |||
): | |||
p.sequentialTimer.schedule("deselectMismatchedTiles", True, p.c.deselectMismatchedTilesDelay) | |||
#} | |||
#} | |||
# Postpone display of the ending splash screen | |||
# | |||
# Conditions: | |||
# 1. just finished removing all tiles | |||
def desktop_scheduleDisplayOfEndingSplashScreen(p): | |||
if ( | |||
p.c.recentField == "victory" | |||
): | |||
p.sequentialTimer.schedule("displayEndingSplashScreen", True, p.c.splashEndDelay) | |||
#} | |||
#} | |||
# Postpone hiding of matching tiles for better UX | |||
# | |||
# Conditions: | |||
# 1. a pair of tiles has been matched | |||
def desktop_scheduleHidingOfMatchingTiles(p): | |||
if ( | |||
p.c.recentField == "hiddenItems" | |||
): | |||
p.sequentialTimer.schedule("hideMatchingTiles", True, p.c.hideMatchingTilesDelay) | |||
#} | |||
#} | |||
# Postpone hiding of the beginning splash screen | |||
# | |||
# Conditions: | |||
# 1. just launched the game | |||
def desktop_scheduleHidingOfBeginningSplashScreen(p): | |||
if ( | |||
p.c.recentField == "splashBeginTimeout" | |||
): | |||
p.sequentialTimer.schedule("hideBeginningSplashScreen", True, p.c.splashBeginTimeout) | |||
#} | |||
#} | |||
@@ -0,0 +1,22 @@ | |||
import arcade | |||
class desktop_Platform: | |||
def __init__(self): | |||
self.c = None | |||
self.ctrl = None | |||
self.desc = None | |||
self.descSprites = arcade.SpriteList() | |||
self.descTextures = [] | |||
self.deselectedSprites = arcade.SpriteList() | |||
self.deselectedTiles = [] | |||
self.mousePosition = [] | |||
self.selectedTiles = [] | |||
self.sequentialTimer = None | |||
self.selectedSprites = arcade.SpriteList() | |||
self.splash = None | |||
self.splashSprites = arcade.SpriteList() | |||
self.splashTextures = [] | |||
self.textures = [] | |||
self.title = None | |||
self.titleSprites = arcade.SpriteList() | |||
self.titleTextures = [] |
@@ -0,0 +1,35 @@ | |||
import time | |||
class desktop_SequentialTimer(): | |||
def __init__(self): | |||
self.activeTimeout = None | |||
self.callback = None | |||
self.queue = [] | |||
#} | |||
def update(self): | |||
# Get current time in milliseconds. | |||
now = time.time_ns() // 1000000 | |||
# Schedule an item. | |||
if ( | |||
self.activeTimeout == None and | |||
len(self.queue) > 0 | |||
): | |||
self.activeTimeout = now + self.queue[0][0] | |||
elif ( | |||
self.activeTimeout != None and | |||
now >= self.activeTimeout | |||
): | |||
# Report when the time is up. | |||
key = self.queue[0][1] | |||
value = self.queue[0][2] | |||
self.queue.pop(0) | |||
self.activeTimeout = None | |||
self.callback(key, value) | |||
#} | |||
#} | |||
def schedule(self, key, value, timeout): | |||
self.queue.append([timeout, key, value]) | |||
#} |
@@ -0,0 +1,32 @@ | |||
import arcade | |||
from desktop_aux import * | |||
class desktop_Window(arcade.Window): | |||
def __init__(self, p): | |||
super().__init__( | |||
p.c.windowWidth, | |||
p.c.windowHeight, | |||
p.c.windowTitle, | |||
) | |||
self.antialiasing = p.c.windowAntialiasing | |||
self.background_color = arcade.color_from_hex_string(p.c.windowBackgroundColor) | |||
self.p = p | |||
def on_draw(self): | |||
arcade.start_render() | |||
self.p.descSprites.draw() | |||
self.p.deselectedSprites.draw() | |||
self.p.selectedSprites.draw() | |||
self.p.splashSprites.draw() | |||
self.p.titleSprites.draw() | |||
def on_mouse_press(self, x, y, button, key_modifiers): | |||
id = desktop_aux_tileIdAt(self.p, x, y) | |||
if ( | |||
id != None | |||
): | |||
self.p.ctrl.set("selectedId", id) | |||
def on_update(self, delta): | |||
self.p.deselectedSprites.update_animation() | |||
self.p.sequentialTimer.update() |
@@ -0,0 +1,13 @@ | |||
import arcade | |||
# Find a visible tile id at the specified location | |||
def desktop_aux_tileIdAt(p, x, y): | |||
sprites = arcade.get_sprites_at_point([x, y], p.deselectedSprites) | |||
if ( | |||
len(sprites) != 0 and | |||
sprites[0].visible | |||
): | |||
return sprites[0].guid | |||
#} | |||
return None | |||
#} |
@@ -0,0 +1,175 @@ | |||
from gui_aux import * | |||
from gui_TextureDescription import * | |||
from llm import * | |||
from memory_Context import * | |||
# Generate texture descriptions for harm description | |||
# | |||
# Conditions: | |||
# 1.descImage, descImageCount, descImageHeight, or descImageWidth has just changed | |||
@llm_by_value | |||
def gui_generateDescTextureDescriptions( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "descImage" or | |||
c.recentField == "descImageCount" or | |||
c.recentField == "descImageHeight" or | |||
c.recentField == "descImageWidth" | |||
): | |||
tds: list[gui_TextureDescription] = [] | |||
for id in range(0, c.descImageCount): | |||
td = gui_createTextureDescription() | |||
td.fileName = c.descImage | |||
td.height = c.descImageHeight | |||
td.width = c.descImageWidth | |||
td.x = id * c.descImageWidth | |||
td.y = 0 | |||
tds.append(td) | |||
#} | |||
c.descTextureDescriptions = tds | |||
c.recentField = "descTextureDescriptions" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Generate texture descriptions for splash screens | |||
# | |||
# Conditions: | |||
# 1.splashImage, splashImageCount, splashImageHeight, or splashImageWidth has just changed | |||
@llm_by_value | |||
def gui_generateSplashTextureDescriptions( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "splashImage" or | |||
c.recentField == "splashImageCount" or | |||
c.recentField == "splashImageHeight" or | |||
c.recentField == "splashImageWidth" | |||
): | |||
tds: list[gui_TextureDescription] = [] | |||
for id in range(0, c.splashImageCount): | |||
td = gui_createTextureDescription() | |||
td.fileName = c.splashImage | |||
td.height = c.splashImageHeight | |||
td.width = c.splashImageWidth | |||
td.x = id * c.splashImageWidth | |||
td.y = 0 | |||
tds.append(td) | |||
#} | |||
c.splashTextureDescriptions = tds | |||
c.recentField = "splashTextureDescriptions" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Generate texture descriptions for tiles | |||
# | |||
# Conditions: | |||
# 1. tileImage or tileImageCount or tileImageHeight or tileImageWidth has just changed | |||
@llm_by_value | |||
def gui_generateTextureDescriptions( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "tileImage" or | |||
c.recentField == "tileImageCount" or | |||
c.recentField == "tileImageHeight" or | |||
c.recentField == "tileImageWidth" | |||
): | |||
tds: list[gui_TextureDescription] = [] | |||
for id in range(0, c.tileImageCount): | |||
td = gui_createTextureDescription() | |||
td.fileName = c.tileImage | |||
td.height = c.tileImageHeight | |||
td.width = c.tileImageWidth | |||
td.x = id * c.tileImageWidth | |||
td.y = 0 | |||
tds.append(td) | |||
#} | |||
c.textureDescriptions = tds | |||
c.recentField = "textureDescriptions" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Generate tile positions | |||
# | |||
# Conditions: | |||
# 1. cellSize, playField, windowHeight, or windowWidth has changed and none of them is zero | |||
@llm_by_value | |||
def gui_generateTilePositions( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
( | |||
c.recentField != "cellPositions" and | |||
c.recentField != "cellSize" and | |||
c.recentField != "playfieldSize" and | |||
c.recentField != "windowHeight" and | |||
c.recentField != "windowWidth" | |||
) or | |||
( | |||
len(c.cellPositions) == 0 or | |||
c.cellSize == 0 or | |||
c.playfieldSize == 0 or | |||
c.windowHeight == 0 or | |||
c.windowWidth == 0 | |||
) | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
ps = [] | |||
for i in range(0, len(c.cellPositions)): | |||
p = gui_aux_cellScreenPosition(c, c.cellPositions[i]) | |||
ps.append(p) | |||
#} | |||
c.tilePositions = ps | |||
c.recentField = "tilePositions" | |||
return c | |||
#} | |||
# Generate texture descriptions for tiTLes | |||
# | |||
# Conditions: | |||
# 1. titleImage, titleImageCount, titleImageHeight, or titleImageWidth has just changed | |||
@llm_by_value | |||
def gui_generateTitleTextureDescriptions( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "titleImage" or | |||
c.recentField == "titleImageCount" or | |||
c.recentField == "titleImageHeight" or | |||
c.recentField == "titleImageWidth" | |||
): | |||
tds: list[gui_TextureDescription] = [] | |||
for id in range(0, c.titleImageCount): | |||
td = gui_createTextureDescription() | |||
td.fileName = c.titleImage | |||
td.height = c.titleImageHeight | |||
td.width = c.titleImageWidth | |||
td.x = id * c.titleImageWidth | |||
td.y = 0 | |||
tds.append(td) | |||
#} | |||
c.titleTextureDescriptions = tds | |||
c.recentField = "titleTextureDescriptions" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} |
@@ -0,0 +1,15 @@ | |||
class gui_TextureDescription: | |||
def __init__(self): | |||
self.fileName = "" | |||
self.height = 0 | |||
self.width = 0 | |||
self.x = 0 | |||
self.y = 0 | |||
def __repr__(self): | |||
return self.__str__() | |||
def __str__(self): | |||
return f"gui_TextureD(fileN/height/width/x/y: '{self.fileName}'/'{self.height}'/'{self.width}'/'{self.x}'/'{self.y}')" | |||
def gui_createTextureDescription(): | |||
return gui_TextureDescription() |
@@ -0,0 +1,78 @@ | |||
from memory_Context import * | |||
# Generate grid positions in cell dimensions | |||
# | |||
# Conditions: | |||
# 1. 2x2 grid | |||
# 2. 4x4 grid | |||
def gui_aux_cellGridPositions( | |||
size: int | |||
) -> [[int]]: | |||
if ( | |||
size == 2 | |||
): | |||
return [ | |||
[14, 7], | |||
[19, 7], | |||
[14, 13], | |||
[19, 13], | |||
] | |||
#} | |||
if ( | |||
size == 4 | |||
): | |||
return [ | |||
[9, 1], | |||
[14, 1], | |||
[19, 1], | |||
[24, 1], | |||
[9, 7], | |||
[14, 7], | |||
[19, 7], | |||
[24, 7], | |||
[9, 13], | |||
[14, 13], | |||
[19, 13], | |||
[24, 13], | |||
[9, 19], | |||
[14, 19], | |||
[19, 19], | |||
[24, 19], | |||
] | |||
#} | |||
#} | |||
# Generate positions in cell dimensions for Harm game | |||
def gui_aux_cellHarmPositions( | |||
) -> [[int]]: | |||
return [ | |||
[4, 6], | |||
[9, 6], | |||
[14, 6], | |||
[19, 6], | |||
[24, 6], | |||
[29, 6], | |||
[4, 12], | |||
[9, 12], | |||
[14, 12], | |||
[4, 18], | |||
[9, 18], | |||
[14, 18], | |||
] | |||
#} | |||
# Convert cell position to screen position | |||
def gui_aux_cellScreenPosition( | |||
c: memory_Context, | |||
pos: [int] | |||
) -> [int]: | |||
x = pos[0] * c.cellSize | |||
y = c.windowHeight - pos[1] * c.cellSize | |||
return [x, y] | |||
#} |
@@ -0,0 +1,15 @@ | |||
from gui_aux import * | |||
def test_gui_aux_cellGridPositions( | |||
) -> str: | |||
items2x2 = gui_aux_cellGridPositions(2) | |||
items4x4 = gui_aux_cellGridPositions(4) | |||
if ( | |||
len(items2x2) == 4 and | |||
len(items4x4) == 16 | |||
): | |||
return "OK: gui_aux_cellGridPositions" | |||
#} | |||
return "ERR: gui_aux_cellGridPositions" | |||
#} |
@@ -0,0 +1,49 @@ | |||
from gui import * | |||
from gui_TextureDescription import * | |||
from memory_Context import * | |||
def test_gui_generateTextureDescriptions( | |||
) -> str: | |||
c = memory_createContext() | |||
c.tileImage = "res/img.png" | |||
c.tileImageCount = 3 | |||
c.tileImageHeight = 35 | |||
c.tileImageWidth = 20 | |||
c.recentField = "tileImageWidth" | |||
c = gui_generateTextureDescriptions(c) | |||
if ( | |||
c.recentField == "textureDescriptions" and | |||
len(c.textureDescriptions) == 3 and | |||
c.textureDescriptions[0].fileName == "res/img.png" and | |||
c.textureDescriptions[0].height == 35 and | |||
c.textureDescriptions[0].width == 20 and | |||
c.textureDescriptions[0].x == 0 and | |||
c.textureDescriptions[1].x == 20 and | |||
c.textureDescriptions[2].x == 40 | |||
): | |||
return "OK: gui_generateTextureDescriptions" | |||
#} | |||
return "ERR: gui_generateTextureDescriptions" | |||
#} | |||
def test_gui_generateTilePositions( | |||
) -> str: | |||
c = memory_createContext() | |||
c.cellSize = 10 | |||
c.playfieldSize = 2 | |||
c.cellPositions = gui_aux_cellGridPositions(c.playfieldSize) | |||
c.windowHeight = 200 | |||
c.windowWidth = 200 | |||
c.recentField = "windowWidth" | |||
c = gui_generateTilePositions(c) | |||
if ( | |||
c.recentField == "tilePositions" and | |||
len(c.tilePositions) == 4 and | |||
c.tilePositions[0][0] == 140 | |||
): | |||
return "OK: gui_generateTilePositions" | |||
#} | |||
return "ERR: gui_generateTilePositions" | |||
#} |
@@ -0,0 +1,22 @@ | |||
import copy | |||
# Make deep copies of arguments to treat the arguments as structs. | |||
# https://stackoverflow.com/a/15398021 | |||
def llm_by_value(f): | |||
def _f(*args, **kwargs): | |||
argsCopy = copy.deepcopy(args) | |||
kwargsCopy = copy.deepcopy(kwargs) | |||
return f(*argsCopy, **kwargsCopy) | |||
return _f | |||
# Tell if string is a digit | |||
def llm_isDigit(s): | |||
return s.isdigit() | |||
# Tell if string starts with certain prefix. | |||
def llm_startsWith(s, prefix): | |||
return s.startswith(prefix) | |||
# Convert string to integer | |||
def llm_strToInt(s): | |||
return int(s) |
@@ -0,0 +1,31 @@ | |||
from llm import * | |||
def llm_test_isDigit_digit( | |||
) -> str: | |||
if ( | |||
llm_isDigit("123") | |||
): | |||
return "OK: llm_isDigit_digit" | |||
#} | |||
return "ERR: llm_isDigit_digit" | |||
#} | |||
def llm_test_isDigit_notDigit( | |||
) -> str: | |||
if ( | |||
llm_isDigit("abc") | |||
): | |||
return "ERR: llm_isDigit_notDigit" | |||
#} | |||
return "OK: llm_isDigit_notDigit" | |||
#} | |||
def llm_test_strToInt( | |||
) -> str: | |||
if ( | |||
llm_strToInt("123") == 123 | |||
): | |||
return "OK: llm_strToInt" | |||
#} | |||
return "ERR: llm_strToInt" | |||
#} |
@@ -0,0 +1,21 @@ | |||
from llm import * | |||
from memory_Context import * | |||
def llm_test_Python_copyByValue( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
@llm_by_value | |||
def alterValue(c): | |||
c.input = "alteredValue" | |||
alterValue(c) | |||
if ( | |||
c.input == "abc" | |||
): | |||
return "OK: llm_Python_copyByValue" | |||
#} | |||
return "ERR: llm_Python_copyByValue" | |||
#} |
@@ -0,0 +1,160 @@ | |||
import arcade | |||
from cli import * | |||
from cli_test import * | |||
from ctx import * | |||
from ctx_test2 import * | |||
from desktop import * | |||
from desktop_Platform import * | |||
from desktop_SequentialTimer import * | |||
from desktop_Window import * | |||
from gui import * | |||
from gui_aux import * | |||
from gui_aux_test import * | |||
from gui_test import * | |||
from llm_test import * | |||
from llm_test_Python import * | |||
from memory_test import * | |||
import sys | |||
print(ctx_test_Controller_executeFunctions_registerFunction_set()) | |||
print(ctx_test_Controller_processQueue()) | |||
print(ctx_test_Controller_registerFieldCallback_match()) | |||
print(ctx_test_Controller_registerFieldCallback_mismatch()) | |||
print(ctx_test_memoryContext_field()) | |||
print(ctx_test_memoryContext_setField()) | |||
print(llm_test_Python_copyByValue()) | |||
print(llm_test_isDigit_digit()) | |||
print(llm_test_isDigit_notDigit()) | |||
print(llm_test_strToInt()) | |||
print(memory_test_detectMismatchedItems()) | |||
print(memory_test_detectMismatchedItems_itemTwice()) | |||
print(memory_test_detectVictory()) | |||
print(memory_test_generateConstPlayfield()) | |||
print(memory_test_hideMatchingItems()) | |||
print(memory_test_selectItem_1x()) | |||
print(memory_test_selectItem_2x()) | |||
print(memory_test_selectItem_3x()) | |||
print(cli_test_exit_e()) | |||
print(cli_test_exit_exit()) | |||
print(cli_test_exit_victory()) | |||
print(cli_test_exit_q()) | |||
print(cli_test_exit_quit()) | |||
print(cli_test_goOn()) | |||
print(cli_test_greetUser()) | |||
print(cli_test_showHelp_h()) | |||
print(cli_test_showHelp_help()) | |||
print(cli_test_selectItem()) | |||
print(cli_test_promptSecondItemSelection()) | |||
print(cli_test_reportMatchedItems()) | |||
print(cli_test_reportMismatchedItems()) | |||
print(cli_test_reportVictory()) | |||
print(test_gui_aux_cellGridPositions()) | |||
print(test_gui_generateTextureDescriptions()) | |||
print(test_gui_generateTilePositions()) | |||
ctrl = ctx_Controller(memory_createContext()) | |||
ctrl.registerFunctions([ | |||
# cli_exit, | |||
# cli_goOn, | |||
# cli_greetUser, | |||
# cli_promptSecondItemSelection, | |||
# cli_reportMatchedItems, | |||
# cli_reportMismatchedItems, | |||
# cli_reportVictory, | |||
# cli_selectItem, | |||
# cli_showHelp, | |||
gui_generateDescTextureDescriptions, | |||
gui_generateSplashTextureDescriptions, | |||
gui_generateTextureDescriptions, | |||
gui_generateTilePositions, | |||
gui_generateTitleTextureDescriptions, | |||
memory_detectMismatchedItems, | |||
memory_detectVictory, | |||
memory_generateConstPlayfield, | |||
memory_hideMatchingItems, | |||
memory_selectItem, | |||
]) | |||
def printDbg(c): | |||
print(f"Dbg key/value: '{c.recentField}'/'{c.field(c.recentField)}'") | |||
ctrl.registerCallback(printDbg) | |||
ctrl.registerFieldCallback("exit", lambda c: sys.exit(0)) | |||
p = desktop_Platform() | |||
p.ctrl = ctrl | |||
p.sequentialTimer = desktop_SequentialTimer() | |||
p.sequentialTimer.callback = lambda key, value: ctrl.set(key, value) | |||
# Bind platform to context changes. | |||
def process(c): | |||
# Copy context to platform. | |||
p.c = c | |||
# Perform context dependent calls of desktop functions. | |||
# Similar to context functions, but no platform is returned. | |||
desktop_deselectMismatchedTiles(p) | |||
desktop_displayDesc(p) | |||
desktop_displayEndingSplashScreen(p) | |||
desktop_displaySelectedTile(p) | |||
desktop_displayTitle(p) | |||
desktop_hideBeginningSplashScreen(p) | |||
desktop_hideDesc(p) | |||
desktop_hideMatchingTiles(p) | |||
desktop_hideTitle(p) | |||
desktop_scheduleDisplayOfEndingSplashScreen(p) | |||
desktop_scheduleHidingOfBeginningSplashScreen(p) | |||
desktop_scheduleHidingOfMatchingTiles(p) | |||
desktop_scheduleDeselectionOfMismatchedTiles(p) | |||
ctrl.registerCallback(process) | |||
ctrl.set("didLaunch", True) | |||
ctrl.set("playfieldSize", 6) | |||
ctrl.set("cellPositions", gui_aux_cellHarmPositions()) | |||
ctrl.set("cellSize", 25) | |||
ctrl.set("deselectMismatchedTilesDelay", 500) | |||
ctrl.set("descImage", "res/harm.png") | |||
ctrl.set("descImageCount", 6) | |||
ctrl.set("descImageHeight", 250) | |||
ctrl.set("descImageWidth", 375) | |||
ctrl.set("descPosition", [19, 12]) | |||
ctrl.set("hideMatchingTilesDelay", 500) | |||
ctrl.set("splashBeginTimeout", 2000) | |||
ctrl.set("splashEndDelay", 100) | |||
ctrl.set("splashImage", "res/splash.png") | |||
ctrl.set("splashImageCount", 2) | |||
ctrl.set("splashImageHeight", 600) | |||
ctrl.set("splashImageWidth", 900) | |||
ctrl.set("tileImage", "res/harmful-tiles.png") | |||
ctrl.set("tileImageCount", 8) | |||
ctrl.set("tileImageHeight", 100) | |||
ctrl.set("tileImageWidth", 75) | |||
ctrl.set("titleImage", "res/harmful-titles.png") | |||
ctrl.set("titleImageCount", 6) | |||
ctrl.set("titleImageHeight", 100) | |||
ctrl.set("titleImageWidth", 700) | |||
ctrl.set("titlePosition", [4, 1]) | |||
ctrl.set("windowWidth", 900) | |||
ctrl.set("windowHeight", 600) | |||
ctrl.set("windowAntialiasing", False) | |||
ctrl.set("windowBackgroundColor", "#ffffff") | |||
ctrl.set("windowTitle", "Вредные продукты") | |||
desktop_loadTextures(p) | |||
desktop_createDeselectedTiles(p) | |||
desktop_createSelectedTiles(p) | |||
desktop_loadTitleTextures(p) | |||
desktop_createTitle(p) | |||
desktop_loadDescTextures(p) | |||
desktop_createDesc(p) | |||
desktop_loadSplashTextures(p) | |||
desktop_createSplash(p) | |||
wnd = desktop_Window(p) | |||
arcade.run() |
@@ -0,0 +1,77 @@ | |||
from cli import * | |||
from cli_test import * | |||
from ctx import * | |||
from ctx_test2 import * | |||
#from ctx_test import * | |||
#from ctx_test_Python import * | |||
from llm_test import * | |||
from llm_test_Python import * | |||
from memory_test import * | |||
import sys | |||
print(ctx_test_Controller_executeFunctions_registerFunction_set()) | |||
print(ctx_test_Controller_processQueue()) | |||
print(ctx_test_Controller_registerFieldCallback_match()) | |||
print(ctx_test_Controller_registerFieldCallback_mismatch()) | |||
print(ctx_test_memoryContext_field()) | |||
print(ctx_test_memoryContext_setField()) | |||
print(llm_test_Python_copyByValue()) | |||
print(llm_test_isDigit_digit()) | |||
print(llm_test_isDigit_notDigit()) | |||
print(llm_test_strToInt()) | |||
print(memory_test_detectMismatchedItems()) | |||
print(memory_test_detectMismatchedItems_itemTwice()) | |||
print(memory_test_detectVictory()) | |||
print(memory_test_generateConstPlayfield()) | |||
print(memory_test_hideMatchingItems()) | |||
print(memory_test_selectItem_1x()) | |||
print(memory_test_selectItem_2x()) | |||
print(memory_test_selectItem_3x()) | |||
print(cli_test_exit_e()) | |||
print(cli_test_exit_exit()) | |||
print(cli_test_exit_victory()) | |||
print(cli_test_exit_q()) | |||
print(cli_test_exit_quit()) | |||
print(cli_test_goOn()) | |||
print(cli_test_greetUser()) | |||
print(cli_test_showHelp_h()) | |||
print(cli_test_showHelp_help()) | |||
print(cli_test_selectItem()) | |||
print(cli_test_promptSecondItemSelection()) | |||
print(cli_test_reportMatchedItems()) | |||
print(cli_test_reportMismatchedItems()) | |||
print(cli_test_reportVictory()) | |||
ctrl = ctx_Controller(memory_createContext()) | |||
ctrl.registerFunctions([ | |||
cli_exit, | |||
cli_goOn, | |||
cli_greetUser, | |||
cli_promptSecondItemSelection, | |||
cli_reportMatchedItems, | |||
cli_reportMismatchedItems, | |||
cli_reportVictory, | |||
cli_selectItem, | |||
cli_showHelp, | |||
memory_detectMismatchedItems, | |||
memory_detectVictory, | |||
memory_generateConstPlayfield, | |||
memory_hideMatchingItems, | |||
memory_selectItem, | |||
]) | |||
def printOutput(c): | |||
if c.recentField.startswith("output"): | |||
print(c.field(c.recentField)) | |||
ctrl.registerCallback(printOutput) | |||
ctrl.registerFieldCallback("exit", lambda c: sys.exit(0)) | |||
ctrl.set("didLaunch", True) | |||
ctrl.set("playfieldSize", 2) | |||
for line in sys.stdin: | |||
ln = line.rstrip() | |||
ctrl.set("input", ln) |
@@ -0,0 +1,138 @@ | |||
from memory_Context import * | |||
from llm import * | |||
# Detect mismatched items | |||
# | |||
# Conditions: | |||
# 0. Two items has just been selected | |||
# 1. The same item has been selected twice | |||
# 2. Selected items are of different groups | |||
@llm_by_value | |||
def memory_detectMismatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 2 | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
if ( | |||
c.selectedItems[0] == c.selectedItems[1] | |||
): | |||
c.mismatchedItems.clear() | |||
c.mismatchedItems.append(c.selectedItems[0]) | |||
c.recentField = "mismatchedItems" | |||
return c | |||
#} | |||
if ( | |||
c.playfieldItems[c.selectedItems[0]] != c.playfieldItems[c.selectedItems[1]] | |||
): | |||
c.mismatchedItems.clear() | |||
c.mismatchedItems.append(c.selectedItems[0]) | |||
c.mismatchedItems.append(c.selectedItems[1]) | |||
c.recentField = "mismatchedItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Detect victory | |||
# | |||
# Conditions: | |||
# 1. Matching items have just been hidden and all items are hidden now | |||
@llm_by_value | |||
def memory_detectVictory( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "hiddenItems" and | |||
len(c.hiddenItems) == len(c.playfieldItems) | |||
): | |||
c.victory = True | |||
c.recentField = "victory" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Generate constant playfield | |||
# | |||
# Conditions: | |||
# 1. Size has just been specified | |||
# | |||
# Both ids and group ids start with 0 | |||
@llm_by_value | |||
def memory_generateConstPlayfield( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "playfieldSize" | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
idGroups: dict[int, int] = { } | |||
id = 0 | |||
for gid in range(0, c.playfieldSize): | |||
idGroups[id] = gid | |||
id += 1 | |||
idGroups[id] = gid | |||
id += 1 | |||
#} | |||
c.playfieldItems = idGroups | |||
c.recentField = "playfieldItems" | |||
return c | |||
#} | |||
# Hide matching selected items | |||
# | |||
# Conditions: | |||
# 1. Two items are selected and they are of the same group | |||
@llm_by_value | |||
def memory_hideMatchingItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 2 and | |||
c.playfieldItems[c.selectedItems[0]] == c.playfieldItems[c.selectedItems[1]] | |||
): | |||
c.hiddenItems.append(c.selectedItems[0]) | |||
c.hiddenItems.append(c.selectedItems[1]) | |||
c.recentField = "hiddenItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Select item | |||
# | |||
# Conditions: | |||
# 1. Id has just been specified for selection | |||
@llm_by_value | |||
def memory_selectItem( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "selectedId" | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
if ( | |||
len(c.selectedItems) == 2 | |||
): | |||
c.selectedItems.clear() | |||
#} | |||
c.selectedItems.append(c.selectedId) | |||
c.recentField = "selectedItems" | |||
return c | |||
#} | |||
@@ -0,0 +1,71 @@ | |||
class memory_Context: | |||
def __init__(self): | |||
self.cellPositions = [] | |||
self.cellSize = 0 | |||
self.descImage = "" | |||
self.descImageCount = 0 | |||
self.descImageHeight = 0 | |||
self.descImageWidth = 0 | |||
self.descPosition = [] | |||
self.descTextureDescriptions = [] | |||
self.deselectMismatchedTiles = False | |||
self.deselectMismatchedTilesDelay = 0 | |||
self.didLaunch = False | |||
self.displayEndingSplashScreen = False | |||
self.exit = False | |||
self.hiddenItems = [] | |||
self.hideBeginningSplashScreen = False | |||
self.hideMatchingTiles = False | |||
self.hideMatchingTilesDelay = 0 | |||
self.input = "" | |||
self.mismatchedItems = [] | |||
self.outputGoOn = "" | |||
self.outputGreeting = "" | |||
self.outputHelp = "" | |||
self.outputMatchedItems = "" | |||
self.outputMismatchedItems = "" | |||
self.outputPromptSelection = "" | |||
self.outputVictory = "" | |||
self.playfieldItems = {} | |||
self.playfieldSize = 0 | |||
self.recentField = "none" | |||
self.selectedId = -1 | |||
self.selectedItems = [] | |||
self.splashBeginTimeout = 0 | |||
self.splashEndDelay = 0 | |||
self.splashImage = "" | |||
self.splashImageCount = 0 | |||
self.splashImageHeight = 0 | |||
self.splashImageWidth = 0 | |||
self.textureDescriptions = [] | |||
self.tileImage = "" | |||
self.tileImageCount = 0 | |||
self.tileImageHeight = 0 | |||
self.tileImageWidth = 0 | |||
self.tilePositions = [] | |||
self.titleImage = "" | |||
self.titleImageCount = 0 | |||
self.titleImageHeight = 0 | |||
self.titleImageWidth = 0 | |||
self.titlePosition = [] | |||
self.titleTextureDescriptions = [] | |||
self.windowBackgroundColor = "#000000" | |||
self.windowHeight = 0 | |||
self.windowTitle = "" | |||
self.windowWidth = 0 | |||
self.victory = False | |||
def field(self, fieldName): | |||
return getattr(self, fieldName) | |||
def setField(self, fieldName, value): | |||
setattr(self, fieldName, value) | |||
def __repr__(self): | |||
return self.__str__() | |||
def __str__(self): | |||
return f"memory_Context(playfieldI/playfieldS/recentF/selectedId/selectedI: '{self.playfieldItems}'/'{self.playfieldSize}'/'{self.recentField}'/'{self.selectedId}'/'{self.selectedItems}')" | |||
def memory_createContext(): | |||
return memory_Context() |
@@ -0,0 +1,231 @@ | |||
from memory import * | |||
from memory_Context import * | |||
def memory_test_detectMismatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select two items of different groups. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Detect mismatching. | |||
c = memory_detectMismatchedItems(c) | |||
# See if the two selected items do not match. | |||
if ( | |||
c.recentField == "mismatchedItems" and | |||
len(c.mismatchedItems) == 2 and | |||
c.mismatchedItems[0] == 0 and | |||
c.mismatchedItems[1] == 2 | |||
): | |||
return "OK: memory_detectMismatchedItems" | |||
#} | |||
return "ERR: memory_detectMismatchedItems" | |||
#} | |||
def memory_test_detectMismatchedItems_itemTwice( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the same item twice. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Detect mismatching. | |||
c = memory_detectMismatchedItems(c) | |||
# See if the two selected items do not match. | |||
if ( | |||
c.recentField == "mismatchedItems" and | |||
len(c.mismatchedItems) == 1 and | |||
c.mismatchedItems[0] == 0 | |||
): | |||
return "OK: memory_detectMismatchedItems_itemTwice" | |||
#} | |||
return "ERR: memory_detectMismatchedItems_itemTwice" | |||
#} | |||
def memory_test_detectVictory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first two items of the same group. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide the first pair. | |||
c = memory_hideMatchingItems(c) | |||
# Select the last two items of the same group. | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 3 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide the second pair. | |||
c = memory_hideMatchingItems(c) | |||
# Detect victory. | |||
c = memory_detectVictory(c) | |||
# See if victory has been detected. | |||
if ( | |||
c.recentField == "victory" and | |||
c.victory == True | |||
): | |||
return "OK: memory_detectVictory" | |||
#} | |||
return "ERR: memory_detectVictory" | |||
#} | |||
def memory_test_generateConstPlayfield( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
if ( | |||
c.recentField == "playfieldItems" and | |||
len(c.playfieldItems) == 4 and | |||
c.playfieldItems[0] == 0 and | |||
c.playfieldItems[1] == 0 and | |||
c.playfieldItems[2] == 1 and | |||
c.playfieldItems[3] == 1 | |||
): | |||
return "OK: memory_generateConstPlayfield" | |||
#} | |||
return "ERR: memory_generateConstPlayfield" | |||
#} | |||
def memory_test_hideMatchingItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select two items of the same group. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide matching items. | |||
c = memory_hideMatchingItems(c) | |||
# See if the two selected items match. | |||
if ( | |||
c.recentField == "hiddenItems" and | |||
len(c.hiddenItems) == 2 and | |||
c.hiddenItems[0] == 0 and | |||
c.hiddenItems[1] == 1 | |||
): | |||
return "OK: memory_hideMatchingItems" | |||
#} | |||
return "ERR: memory_hideMatchingItems" | |||
#} | |||
def memory_test_selectItem_1x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first item. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if it's in selectedItems now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 and | |||
c.selectedItems[0] == 0 | |||
): | |||
return "OK: memory_selectItem_1x" | |||
#} | |||
return "ERR: memory_selectItem_1x" | |||
#} | |||
def memory_test_selectItem_2x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first two items. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if both items are selected now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 2 and | |||
c.selectedItems[0] == 0 and | |||
c.selectedItems[1] == 1 | |||
): | |||
return "OK: memory_selectItem_2x" | |||
#} | |||
return "ERR: memory_selectItem_2x" | |||
#} | |||
def memory_test_selectItem_3x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select three items. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if only one (last) item is selected now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 and | |||
c.selectedItems[0] == 2 | |||
): | |||
return "OK: memory_selectItem_3x" | |||
#} | |||
return "ERR: memory_selectItem_3x" | |||
#} |
@@ -0,0 +1,2 @@ | |||
#!/bin/bash | |||
/Users/mk/py3.12venv/bin/python3.12 main-gui.py |