@@ -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 |