diff --git a/Makefile b/Makefile index a6f2c0f80..21728c942 100644 --- a/Makefile +++ b/Makefile @@ -213,6 +213,16 @@ attract: compress bin/check-attract-mode.sh bin/generate-mini-attract-mode.sh +cache: md + awk -F= '/^00/ { print $$2 }' < res/GAMES.CONF | bin/buildcache.py > build/cache00.a + awk -F= '/^0/ { print $$2 }' < res/GAMES.CONF | bin/buildcache.py > build/cache01.a + awk -F= '/^.0/ { print $$2 }' < res/GAMES.CONF | bin/buildcache.py > build/cache10.a + awk -F= '!/^$$|^#|^\[/ { print $$2 }' < res/GAMES.CONF | bin/buildcache.py > build/cache11.a + $(ACME) -o res/CACHE00.IDX build/cache00.a + $(ACME) -o res/CACHE01.IDX build/cache01.a + $(ACME) -o res/CACHE10.IDX build/cache10.a + $(ACME) -o res/CACHE11.IDX build/cache11.a + mount: dsk osascript bin/V2Make.scpt "`pwd`" bin/4cade.vii build/"$(DISK)" diff --git a/bin/buildcache.py b/bin/buildcache.py new file mode 100755 index 000000000..6529c80f9 --- /dev/null +++ b/bin/buildcache.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +from collections import OrderedDict +from pprint import pprint +from string import ascii_lowercase +from sys import stdin + +def score(inputbuffer, displayname): + if len(inputbuffer) > len(displayname): + return 0, False + likely = True + startat = 0 + score = 0 + for c in inputbuffer: + x = 10 + y = displayname[startat:].find(c) + if y < 0: + return 0, False + if y == 0: + x = 80 + elif (startat > 0) and (displayname[startat+y-1] == " "): + x = 90 + else: + likely = False + score += x + startat += y + 1 + score = int((score/len(displayname)) + (score/len(inputbuffer))+0.99) + if (inputbuffer[0] == displayname[0]) and (score < 85): + score += 15 + return score, likely + +def best(keys, games): + gameindex = 0 + bestscore = -1 + bestindex = -1 + bestlikely = False + for game in games: + gamescore, likely = score(keys, game) + if (gamescore > bestscore): + bestscore = gamescore + bestindex = gameindex + bestlikely = likely + gameindex += 1 + if not bestlikely: + return 0 + return bestindex + +def main(): + games = [line.strip().lower() for line in stdin] + cache = OrderedDict() + for a in ascii_lowercase: + index1 = best(a, games) + if not index1: continue + cache[a] = OrderedDict() + cache[a][" "] = index1 + for b in ascii_lowercase: + index2 = best(a+b, games) + if not index2: continue + cache[a][b] = OrderedDict() + if index2 != index1: + cache[a][b][" "] = index2 + for c in ascii_lowercase: + index3 = best(a+b+c, games) + if not index3: continue + cache[a][b][c] = OrderedDict() + if index3 != index2: + cache[a][b][c][" "] = index3 + for d in ascii_lowercase: + index4 = best(a+b+c+d, games) + if not index4: continue + if index4 != index3: + cache[a][b][c][d] = index4 + if (len(cache[a][b][c]) == 1) and (" " in cache[a][b][c]): + cache[a][b][c] = cache[a][b][c][" "] + elif not cache[a][b][c]: + del cache[a][b][c] + if (len(cache[a][b]) == 1) and (" " in cache[a][b]): + cache[a][b] = cache[a][b][" "] + elif not cache[a][b]: + del cache[a][b] + if (len(cache[a]) == 1) and (" " in cache[a]): + cache[a] = cache[a][" "] + elif not cache[a]: + del cache[a] + + print('*=$B000') + for a in cache: + print(f' !text "{a}"') + if type(cache[a]) == int: + print(f' !word {cache[a]}') + else: + print(f' !word _{a}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + print(f'_{a}') + for b in cache[a]: + print(f' !text "{b}"') + if type(cache[a][b]) == int: + print(f' !word {cache[a][b]}') + else: + print(f' !word _{a}{b}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + for b in cache[a]: + if type(cache[a][b]) == int: continue + print(f'_{a}{b}') + for c in cache[a][b]: + print(f' !text "{c}"') + if type(cache[a][b][c]) == int: + print(f' !word {cache[a][b][c]}') + else: + print(f' !word _{a}{b}{c}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + for b in cache[a]: + if type(cache[a][b]) == int: continue + for c in cache[a][b]: + if type(cache[a][b][c]) == int: continue + print(f'_{a}{b}{c}') + for d in cache[a][b][c]: + print(f' !text "{d}"') + print(f' !word {cache[a][b][c][d]}') + print(' !byte 0') + +main() diff --git a/res/CACHE00.IDX b/res/CACHE00.IDX new file mode 100644 index 000000000..ffc25544e Binary files /dev/null and b/res/CACHE00.IDX differ diff --git a/res/CACHE01.IDX b/res/CACHE01.IDX new file mode 100644 index 000000000..aa4864c8c Binary files /dev/null and b/res/CACHE01.IDX differ diff --git a/res/CACHE10.IDX b/res/CACHE10.IDX new file mode 100644 index 000000000..512225830 Binary files /dev/null and b/res/CACHE10.IDX differ diff --git a/res/CACHE11.IDX b/res/CACHE11.IDX new file mode 100644 index 000000000..e1b521d3a Binary files /dev/null and b/res/CACHE11.IDX differ diff --git a/res/notes/search-cache.txt b/res/notes/search-cache.txt new file mode 100644 index 000000000..caf8ddeab --- /dev/null +++ b/res/notes/search-cache.txt @@ -0,0 +1,71 @@ +; Search cache +; +; each record is 3 bytes +; byte 0: +; character or 0 (EOF) +; bytes 1-2: +; byte 2 bit 7=1 -> absolute address of subindex +; byte 2 bit 7=0 -> numerical index into gSearchStore +; +Root + !text "a" + !word a + + ;...b-z... + + !byte 0 ; EOF -> no cache hit +a + !text " " ; 'a' matches game index 1 + !word 1 + !text "a" + !word aa + !text "b" + !word ab + !text "c" + !word ac + !text "d" + !word ad + !text "f" + !word af + !text "g" + !word ag + !text "i" + !word ai + !text "l" + !word al + !text "m" + !word am + !text "n" + !word an + !text "p" + !word ap + !text "q" + !word aq + !text "r" + !word ar + !text "s" + !word as + !text "t" + !word at + !text "u" + !word au + !text "x" + !word ax + !text "z" + !word az + !byte 0 ; EOF -> no cache hit + +; +;... b-z indexes ... +; + +aa + !text " " ; 'aa' -> game index 3 + !word 3 + !text "a" ; 'aaa' -> 23 + !word 23 + !text "m" ; 'aam' -> 6 + !word 6 + !text "s" ; 'aas' -> 29 + !word 29 + !byte 0 ; EOF -> no cache hit