ZXwordle

People are still making stuff for the Sinclair related machines. Tell us about new games and other software that runs on the Spectrum, ZX80/ZX81, Pentagon and Next.
Post Reply
User avatar
Andre Leao
Bugaboo
Posts: 3145
Joined: Mon Nov 13, 2017 9:28 am
Location: Portugal
Contact:

ZXwordle

Post by Andre Leao »

User avatar
R-Tape
Site Admin
Posts: 6397
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXwordle

Post by R-Tape »

Fantastic! I'm late to the party as ever, and only last week got into the daily Wordle fix. I also considered coding a ZX version too.

Is anyone in touch with Adam Ainsworth? I'm adding the screens and stuff now, can we preserve the TAP too?
User avatar
Joefish
Rick Dangerous
Posts: 2058
Joined: Tue Nov 14, 2017 10:26 am

Re: ZXwordle

Post by Joefish »

Isn't the point of Wordle that each guess has to be a valid word itself?
User avatar
R-Tape
Site Admin
Posts: 6397
Joined: Thu Nov 09, 2017 11:46 am

Re: ZXwordle

Post by R-Tape »

Joefish wrote: Wed Jan 19, 2022 2:22 pm Isn't the point of Wordle that each guess has to be a valid word itself?
Yep, but you'd only be cheating yourself. :mrgreen:

Oddly this game occupies nearly 32K. It could surely be done in 4K or even 1, leaving loads of space for a dictionary. That could be a fun project.
User avatar
Andre Leao
Bugaboo
Posts: 3145
Joined: Mon Nov 13, 2017 9:28 am
Location: Portugal
Contact:

Re: ZXwordle

Post by Andre Leao »

R-Tape wrote: Wed Jan 19, 2022 2:20 pm Fantastic! I'm late to the party as ever, and only last week got into the daily Wordle fix. I also considered coding a ZX version too.

Is anyone in touch with Adam Ainsworth? I'm adding the screens and stuff now, can we preserve the TAP too?
I am and I will ask for a tap :)
User avatar
Andre Leao
Bugaboo
Posts: 3145
Joined: Mon Nov 13, 2017 9:28 am
Location: Portugal
Contact:

Re: ZXwordle

Post by Andre Leao »

Dave, game is not complete yet, but Adam will make it available soon
User avatar
stupidget
Dynamite Dan
Posts: 1629
Joined: Wed Jan 24, 2018 2:09 pm
Location: Sunny Wolverhampton

Re: ZXwordle

Post by stupidget »

I've heard of this Wordle thing but I have no idea what it is. Would someone care to explain?
Last edited by stupidget on Wed Jan 19, 2022 5:52 pm, edited 1 time in total.
User avatar
8BitAG
Dynamite Dan
Posts: 1493
Joined: Sun Dec 17, 2017 9:25 pm
Contact:

Re: ZXwordle

Post by 8BitAG »

It's like the old board game "Mastermind" but you're guessing the letters of a word.

(The idea of doing the game with words apparently pre-dates the peg-based Mastermind)
8-bit Text Adventure Gamer - games - research.
User avatar
Pobulous
Dynamite Dan
Posts: 1358
Joined: Wed Nov 15, 2017 12:51 pm

Re: ZXwordle

Post by Pobulous »

stupidget wrote: Wed Jan 19, 2022 4:11 pm I've heard of this Wordle thing but I have no idea what it is. Would someone car to explain?
I didn't know either and just found this online one:
https://www.powerlanguage.co.uk/wordle/

I like the way it plays - there's more logic and strategy than Mastermind.
Definitely be good to get a 5 letter wordlist in there - could certainly be done in 128K, using one of the smaller lists of around 9000 or less.
adam
Drutt
Posts: 17
Joined: Tue Jul 23, 2019 4:49 pm

Re: ZXwordle

Post by adam »

Hi all,

thank you very much for the interest. I had a brainwave about Wordle last week and spent the weekend coding it. I've been working very hard on a couple of other projects recentyl, so it was nice to take a break.

The thing is, I don't really know Z80 and wanted to get it out quickly while it was still a hot topic, so wrote it in BASIC and used Hisoft's Colt to compile it. If you are in the FB group Spectrum For Everyone, you may have seen me post about compilers yesterday.

Andre unknowingly shared it this morning as I'd posted a message in another group without saying it's not quite finished. I need to add some instructions and reduce it from 32k down to a reasonable size - as has been noted above. At the moment it only has 1,000 words which is enough to have plenty of fun playing it but not enough to enforce valid words as guesses. I guess if it were written in Z80, you'd probably have a good 30-odd kb for the dictionary, which would give you 6,000 five letter words - probably enough to allow for checking.

As you can see, I'm not really an artist either but as I said, I just wanted to launch it quickly. I'm going to be tarting it up this evening and when I get a chance tomorrow and will formally release it either tomorrow evening or Friday morning. As it is literally the first 'proper' game I've ever written for the Speccy, I'm a little nervous about it.

Thank you very much once again for having a look, and I hope you enjoy it when it is out.

Adam :-)
User avatar
Neil Parsons
Manic Miner
Posts: 386
Joined: Thu Nov 23, 2017 6:19 pm

Re: ZXwordle

Post by Neil Parsons »

I downloaded the unfinished version yesterday, when it was available from André Leao blog, and one thing I could suggest is to use a different color for used letters on alphabet board instead of WHITE and BRIGHT 0. If using the game on real hardware and a monitor with scanlines, it would be difficult to distinguish these used letters from the rest. Maybe cyan or red color could be a good choice.

Well, after testing it I find it more enjoyable than the original online game.

Keep the good work Adam. :)
adam
Drutt
Posts: 17
Joined: Tue Jul 23, 2019 4:49 pm

Re: ZXwordle

Post by adam »

Thanks very much for the feedback. I did briefly change them to red but then the code changed and it would have been extra effort to do that!!

I will implement it instead of being lazy
adam
Drutt
Posts: 17
Joined: Tue Jul 23, 2019 4:49 pm

Re: ZXwordle

Post by adam »

Hi all,

I have now (finally) released it - I hope you enjoy it!

https://adamainsworth.co.uk/portfolio/zx-wordle/

Please let me know if you have any feedback, but bear in mind this is my first ever release, and was done in my spare time over the last week or so.

PS I'm gutted that I was beaten to it by a BBC version!
User avatar
evilpaul
Manic Miner
Posts: 244
Joined: Tue Jul 28, 2020 8:04 am
Location: Espoo, Finland
Contact:

Re: ZXwordle

Post by evilpaul »

adam wrote: Wed Jan 19, 2022 8:30 pm At the moment it only has 1,000 words which is enough to have plenty of fun playing it but not enough to enforce valid words as guesses. I guess if it were written in Z80, you'd probably have a good 30-odd kb for the dictionary, which would give you 6,000 five letter words - probably enough to allow for checking.
I've done some thinking..... the official Scrabble dictionary that I found has 8938 5 letter words in it. Storing this naively (5 bytes per words) takes over 43k. Packing the bits (5 bits per letter) already gets us down to a little over 27k. Delta packing would be a good next step. Turns out that there are only a few hundred unique deltas between the words. That's small enough that you could store each delta as two bytes if you used a dictionary. Now we're at about 17.5k for the words plus a k or two for the dictionary, so <20k. My gut says this would fit in 16k.

Hmm.. ok.. let's write some quick code...

Right, my code shows 714 unique deltas (so each delta would pack to 10 bits) with the largest deltas needing three bytes of storage. That means 8938*10bits = 11k for the delta-packed words, and 667*3bytes = 2k for the dictionary. That's 13k in total. You could probably go smaller still.

Searching that list however... not sure how slow that would be in Z80. But that's maybe not a problem given the style of game.

(fingers crossed that my maths is right...)
adam
Drutt
Posts: 17
Joined: Tue Jul 23, 2019 4:49 pm

Re: ZXwordle

Post by adam »

Sorry, only just saw this - nice work on the research.

I would posit that you wouldn't need a whole dictionary, half the words uncompressed would fit in the space left by an efficiently coded version. Searching that ought to be fairly quick then.

If you did want to go the whole hog, you could have a combination of compression, deltas and indexing by first letter but there must be some words that almost no one would ever know, let alone use as a guess in Wordle.
Andrew771
Drutt
Posts: 42
Joined: Mon May 04, 2020 9:59 pm
Location: Moscow, Russia

Re: ZXwordle

Post by Andrew771 »

evilpaul wrote: Fri Jan 21, 2022 9:12 am Searching that list however... not sure how slow that would be in Z80. But that's maybe not a problem given the style of game.

(fingers crossed that my maths is right...)
I already implemented 5-bit dictionary archiving in 2012 for "Erudit" (Russian scrabble) and "Sexwords" games (in Russian):
https://zx-pk.ru/threads/18425-erudit.h ... post717341
https://zx-pk.ru/threads/23903-sexwords.html

Erudit: 14357 words from 2 to 8 letters, 33389 bytes
Sexwords: 7158 words from 2 to 6 letters, 14206 bytes

Russian has 33 letters (I use 32 letters, Е and Ё allowed to combine), average word have 6 letters. English has 26 letters, average word have 5 letters. Therefore English is archived even more.

Archiver is written in Delphi. Algorithm:

Words must be reversed and sorted alphabetically in the source dictionary in text file for PC. Words are reversed, because many identical word endings.

curr_i: the number of first letters of the current word that are the same as the previous word
k: number of letters in the current word
bit_string: a string with a sequence of bits

Formation of a sequence of bits:

Code: Select all

1. Writing the 5-bit parameter of the current word:

        if ((curr_i=0) and (k=2)) then bit_string:=bit_string+'00000';
        if ((curr_i=1) and (k=2)) then bit_string:=bit_string+'00001';
        if ((curr_i=0) and (k=3)) then bit_string:=bit_string+'00010';
        if ((curr_i=1) and (k=3)) then bit_string:=bit_string+'00011';
        if ((curr_i=2) and (k=3)) then bit_string:=bit_string+'00100';
        if ((curr_i=0) and (k=4)) then bit_string:=bit_string+'00101';
        if ((curr_i=1) and (k=4)) then bit_string:=bit_string+'00110';
        if ((curr_i=2) and (k=4)) then bit_string:=bit_string+'00111';
        if ((curr_i=3) and (k=4)) then bit_string:=bit_string+'01000';
        if ((curr_i=0) and (k=5)) then bit_string:=bit_string+'01001';
        if ((curr_i=1) and (k=5)) then bit_string:=bit_string+'01010';
        if ((curr_i=2) and (k=5)) then bit_string:=bit_string+'01011';
        if ((curr_i=3) and (k=5)) then bit_string:=bit_string+'01100';
        if ((curr_i=4) and (k=5)) then bit_string:=bit_string+'01101';
        if ((curr_i=0) and (k=6)) then bit_string:=bit_string+'01110';
        if ((curr_i=1) and (k=6)) then bit_string:=bit_string+'01111';
        if ((curr_i=2) and (k=6)) then bit_string:=bit_string+'10000';
        if ((curr_i=3) and (k=6)) then bit_string:=bit_string+'10001';
        if ((curr_i=4) and (k=6)) then bit_string:=bit_string+'10010';
        if ((curr_i=5) and (k=6)) then bit_string:=bit_string+'10011';
        if ((curr_i=0) and (k=7)) then bit_string:=bit_string+'10100';
        if ((curr_i=1) and (k=7)) then bit_string:=bit_string+'10101';
        if ((curr_i=2) and (k=7)) then bit_string:=bit_string+'10110';
        if ((curr_i=3) and (k=7)) then bit_string:=bit_string+'10111';
        if ((curr_i=4) and (k=7)) then bit_string:=bit_string+'11000';
        if ((curr_i=5) and (k=7)) then bit_string:=bit_string+'11001';
        if ((curr_i=0) and (k=8)) then bit_string:=bit_string+'11010';
        if ((curr_i=1) and (k=8)) then bit_string:=bit_string+'11011';
        if ((curr_i=2) and (k=8)) then bit_string:=bit_string+'11100';
        if ((curr_i=3) and (k=8)) then bit_string:=bit_string+'11101';
        if ((curr_i=4) and (k=8)) then bit_string:=bit_string+'11110';
        if ((curr_i=5) and (k=8)) then bit_string:=bit_string+'11111';

2. The remaining unequal letters of the current word are written sequentially with their 5-bit codes:

              'а': bit_string:=bit_string+'00000';
              'б': bit_string:=bit_string+'00001';
              'в': bit_string:=bit_string+'00010';
              'г': bit_string:=bit_string+'00011';
              'д': bit_string:=bit_string+'00100';
              'е': bit_string:=bit_string+'00101';
              'ж': bit_string:=bit_string+'00110';
              'з': bit_string:=bit_string+'00111';
              'и': bit_string:=bit_string+'01000';
              'й': bit_string:=bit_string+'01001';
              'к': bit_string:=bit_string+'01010';
              'л': bit_string:=bit_string+'01011';
              'м': bit_string:=bit_string+'01100';
              'н': bit_string:=bit_string+'01101';
              'о': bit_string:=bit_string+'01110';
              'п': bit_string:=bit_string+'01111';
              'р': bit_string:=bit_string+'10000';
              'с': bit_string:=bit_string+'10001';
              'т': bit_string:=bit_string+'10010';
              'у': bit_string:=bit_string+'10011';
              'ф': bit_string:=bit_string+'10100';
              'х': bit_string:=bit_string+'10101';
              'ц': bit_string:=bit_string+'10110';
              'ч': bit_string:=bit_string+'10111';
              'ш': bit_string:=bit_string+'11000';
              'щ': bit_string:=bit_string+'11001';
              'ъ': bit_string:=bit_string+'11010';
              'ы': bit_string:=bit_string+'11011';
              'ь': bit_string:=bit_string+'11100';
              'э': bit_string:=bit_string+'11101';
              'ю': bit_string:=bit_string+'11110';
              'я': bit_string:=bit_string+'11111';

3. Go to item 1 for next word.
Assembler code for one word reading from archieved dictionary:

Input parameters:
(tek_slovo) = word address in dictionary
(param_slovo) = quantity of letters in word (high), begin bit number (low)

Output parameters:
CY=1, if the word matches the length
(podbor_slovo) = word (1 letter = 1 byte)
(tek_slovo) = address of the next word in the dictionary
(param_slovo) = quantity of letters in next word (high), begin bit number (low)

Code: Select all

podbor_slovo		dup	8			; текущее подбираемое слово
			defb	0
			edup

param_slovo		defw	0			; количество букв в текущем слове (high), номер бита чтения в словаре (low)

tek_slovo		defw	0			; адрес текущего слова в словаре

Code: Select all

; Алгоритм чтения слова из словаря

; 1. Читаем текущий адрес в словаре
; 2. Читаем текущий бит в словаре
; 3. В зависимости от бита в словаре, читаем параметр слова в последовательности битов, устанавливаем бит в словаре и устанавливаем адрес в словаре
; 4. В зависимости от параметра слова, по таблице читаем количество одинаковых букв с предыдущим словом и количество оставшихся букв в слове
; 5. В зависимости от количества одинаковых букв, устанавливаем адрес в подбираемом слове
; 6. Цикл по количеству оставшихся букв
; 	6а. В зависимости от бита в словаре, читаем букву
; 	6б. Записываем букву в подбираемом слове
; 	6в. Устанавливаем бит в словаре
; 	6г. Устанавливаем адрес в словаре
; 7. Количество букв в слове из словаря = количество одинаковых букв с предыдущим словом + количество оставшихся букв в слове
; 8. Если количество букв в слове из словаря = количество букв в подбираемом слове, то CY=1, иначе CY=0


read_word		ld	hl,(tek_slovo)
			ld	a,(param_slovo)
			ld	b,a

			djnz	read_word_param_0234567

read_word_param_1	ld	a,(hl)
			and	%00000011
			rlca
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11100000
			rlca
			rlca
			rlca
			or	c
			push	hl
			call	read_word_01
			pop	hl
			jp	read_word_bukva_4

read_word_param_0234567	djnz	read_word_param_034567

read_word_param_2	ld	a,(hl)
			and	%00000111
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11000000
			rlca
			rlca
			or	c
			push	hl
			call	read_word_01
			pop	hl
			jp	read_word_bukva_5

read_word_param_034567	djnz	read_word_param_04567

read_word_param_3	ld	a,(hl)
			and	%00001111
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%10000000
			rlca
			or	c
			push	hl
			call	read_word_01
			pop	hl
			jp	read_word_bukva_6

read_word_param_04567	djnz	read_word_param_0567

read_word_param_4	ld	a,(hl)
			and	%00011111
			call	read_word_01
			ld	hl,(tek_slovo)
			inc	hl
			jp	read_word_bukva_7

read_word_param_0567	djnz	read_word_param_067

read_word_param_5	ld	a,(hl)
			and	%00111110
			rrca
			call	read_word_01
			ld	hl,(tek_slovo)
			jp	read_word_bukva_0

read_word_param_067	djnz	read_word_param_07

read_word_param_6	ld	a,(hl)
			and	%01111100
			rrca
			rrca
			call	read_word_01
			ld	hl,(tek_slovo)
			jp	read_word_bukva_1

read_word_param_07	djnz	read_word_param_0

read_word_param_7	ld	a,(hl)
			and	%11111000
			rrca
			rrca
			rrca
			call	read_word_01
			ld	hl,(tek_slovo)
			jp	read_word_bukva_2

read_word_param_0	ld	a,(hl)
			and	%00000001
			rlca
			rlca
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11110000
			rrca
			rrca
			rrca
			rrca
			or	c
			push	hl
			call	read_word_01
			pop	hl


read_word_bukva_3	ld	a,(hl)
			and	%00001111
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%10000000
			rlca
			or	c
			ld	(de),a
			inc	de
			djnz	read_word_bukva_6
			ld	a,6
			jp	read_word_03

read_word_bukva_6	ld	a,(hl)
			and	%01111100
			rrca
			rrca
			ld	(de),a
			inc	de
			djnz	read_word_bukva_1
			ld	a,1
			jp	read_word_03

read_word_bukva_1	ld	a,(hl)
			and	%00000011
			rlca
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11100000
			rlca
			rlca
			rlca
			or	c
			ld	(de),a
			inc	de
			djnz	read_word_bukva_4
			ld	a,4
			jp	read_word_03

read_word_bukva_4	ld	a,(hl)
			and	%00011111
			ld	(de),a
			inc	de
			inc	hl
			djnz	read_word_bukva_7
			ld	a,7
			jp	read_word_03

read_word_bukva_0	ld	a,(hl)
			and	%00000001
			rlca
			rlca
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11110000
			rrca
			rrca
			rrca
			rrca
			or	c
			ld	(de),a
			inc	de
			djnz	read_word_bukva_3
			ld	a,3
			jp	read_word_03

read_word_bukva_7	ld	a,(hl)
			and	%11111000
			rrca
			rrca
			rrca
			ld	(de),a
			inc	de
			djnz	read_word_bukva_2
			ld	a,2
			jp	read_word_03

read_word_bukva_2	ld	a,(hl)
			and	%00000111
			rlca
			rlca
			ld	c,a
			inc	hl
			ld	a,(hl)
			and	%11000000
			rlca
			rlca
			or	c
			ld	(de),a
			inc	de
			djnz	read_word_bukva_5
			ld	a,5
			jp	read_word_03

read_word_bukva_5	ld	a,(hl)
			and	%00111110
			rrca
			ld	(de),a
			inc	de
			djnz	read_word_bukva_0
			xor	a


; a = бит чтения, hl = адрес чтения в словаре

read_word_03		ld	(tek_slovo),hl
			ld	(param_slovo),a

			ld	a,(kol_bukv_word_slovar)
			ld	hl,param_slovo+1
			cp	(hl)
			jp	nz,read_word_05


; количество букв соответствует подбираемому слову

			ld	de,slovo_iz_slovar
			ld	hl,podbor_slovo
			ld	c,a
			dec	c
			ld	b,0
			add	hl,bc
			ld	b,a
			
read_word_04		ld	a,(de)
			ld	(hl),a
			inc	de
			dec	hl
			djnz	read_word_04

			scf
			ret

read_word_05		scf					; количество букв не соответствует подбираемому слову
			ccf
			ret



; a = параметр слова в словаре
; b = количество оставшихся букв в слове, de = адрес в подбираемом слове

read_word_01		ld	b,0
			rlca
			ld	c,a
			ld	hl,table_param_slovar
			add	hl,bc

			ld	e,(hl)				; e = количество одинаковых букв с предыдущим словом
			inc	hl
			ld	a,(hl)
			ld	b,a				; b = количество оставшихся букв в слове
			add	a,e
			ld	(kol_bukv_word_slovar),a	; a = количество букв в слове

			ld	hl,slovo_iz_slovar
			ld	d,0
			add	hl,de
			ex	de,hl				; de = адрес в подбираемом слове

			ret
Coder of ZXOOM, Euphoria 2D, ZX Like Pascal, Russian Railway Magnate...
Andrew771
Drutt
Posts: 42
Joined: Mon May 04, 2020 9:59 pm
Location: Moscow, Russia

Re: ZXwordle

Post by Andrew771 »

I think, that the delta can be made with only 2 bits: it shows the difference by 1,2,3 or 4 letters (00, 01, 10, 11) from the previous word, and encode non-repeating letters in 5 bits
Coder of ZXOOM, Euphoria 2D, ZX Like Pascal, Russian Railway Magnate...
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZXwordle

Post by Dr beep »

Hmm

242 5 letter words and a full game in 1K memory.

https://spectrumcomputing.co.uk/entry/35184/ZX81/Lingo
Post Reply