3D Chess 2K18

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

With a little inspiration, I’ve come up with an additional layer of compression that finally drops the data to probably just under 256 bytes. This then allows easier faster addressing as you might imagine. The pieces are currently build up line by line. The new method maps which lines belong to which pieces. This allows me to remove several repeated lines and though the map data is a new addition separate to the graphics data, it supersedes the current piece data table, also hopefully allowing easier decoding too. I’m not sure yet, but there may now be a real possibility of breaking the 600 byte barrier with a little more effort. Once upon a time I was amazed to have broken through below 1kb!!
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

A quite extreme amount of changes to the code structure and decoding have been experimented with for a couple of weeks, and I think I'm just about there. Still a minor decoding fault, but it runs and bloody fast too. By no means all of the intended changes and ideas have been implemented yet, so it is currently bigger than I hope it will eventually be.

The entire graphics data is now at 251 bytes (version 1 was 382!).

So as it stands, very nearly fully operational, its 612 bytes!

There are a few quick and dirty workarounds just to get a few things going as intended, which will improve with age no doubt. It is now perilously close to breaking the -600 bytes barrier, which even I'm astounded by.

As soon as its fully fixed, I'll post a video, then hopefully some source too.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Finally! After identifying a few silly mistakes and oddities in the code, the bugs have been squished to the point where it runs all ok;

Image

Looking fairly quick, though it will improve. The delays have been trying to figure out the correct decoding of the graphics data. I tend to encode the graphics, then code something to decode that format, and as I go along, often find optimisations, or better methods of encoding that make the decoder faster or smaller. The graphics data is 256 bytes now, making addressing possible with low byte INCs only, saving a few T-states along the way.

Several parts are due for improvement now that the mechanics of the system have been figured out, so expect quite a few bytes to be shed soon, which is why I'll not post any source yet. Inefficient source is just not pretty!

Current size 620 bytes!
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Already now down to 618 bytes!

EDIT: now 615 bytes. ;)
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

I'm sure everyones long since lost interest in this now :shock:

However, its making steady downward progress towards sub 600 bytes.

Now at 609 bytes
User avatar
PaddyC13
Drutt
Posts: 20
Joined: Fri Mar 09, 2018 4:46 pm
Location: UK

Re: 3D Chess 2K18

Post by PaddyC13 »

Nope, not lost interest at all. I would love to see a full blown Chess game created with it though.

Paddy
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Tidying up the source will of course take time, however as a rather raw taster perhaps, and full of poor programming;

Code: Select all

;Chess 2K18 Version 2A 002
;
;July 2018 Arkannoyed-JES
;
;Significant changes to the way the data is constructed have allowed the
;code to become much faster and more efficient, also allowing the gfx
;data to vastly reduce in size.
;
;standard lines consist of 4 bits of data and a length of C (Black or White) infill
;data lines consist of 4 types
;1. long lines. These are lines of 18, 20 or 22 bits length, where the additional 6 bits over 16
;are stored within the index (first) byte, followed by 4 bytes of BWBW arranged data
;2. mini lines. Lines of 8 bits length or less, where left and right bytes are mirrored, so the
;4 bits are stored in the low 4 bits of the index byte.
;3. BLR-WLR lines. The Black and White versions of the line are different, but their Right and Left sides
;are mirrored versions of each other, where the low 5 bits of the index byte hold a XOR overlay to create
; the Black version from the White data. If the XOR ooverlay is 00000 then there is no change applied.
;4. BWR-BWL lines. These lines are non-mirrored, but Black and White are the same, so the low 5 bits in the
;index are added to the Left side to create the Right.
;
;the line Buffers are HL and DE where the MSB is the innermost and they are written outwards right for DE
; and left for HL.
;The last bit in the buffer is always '1' and is inverted to '0' and written, then the printing ends.
;
;Currently this isn't a very fast method for longer lines, however needs no mask as such.
; Work is progressing to auto-mask the printing byte-wise instead, probably speeding things up and 
; possibly saving space too.
;
;
org 0fd00h
gfx_data:
           db 00h                                           ;these 3x00h bytes ensure the piece
           db 00h                                           ;prints after 3 lines of the board square
           db 00h                                           ;have been printed.

           db 81h                                           ;base
           db 0a0h,0f2h
           db 0e4h,0feh,0eh,0feh,0eh
           db 0f6h,0ffh,05h,0f9h,01h
           db 3fh
           db 5fh
           db 3fh
           db 5fh
           db 0dbh,1fh,0e3h,1ch,0e0h
           db 0dbh,0e3h,1dh,0e2h,1ch
           db 0f6h,0fch,0bh,0f5h,01h
           db 0e4h,0feh,02eh,0eah,02h                       ;40b

           db 5ch                                           ;king 28 ;28 Pawn & Knight switch
           db 5bh
           db 2bh
           db 5bh
           db 2bh
           db 2ah
           db 5ah
           db 2ah
           db 5ah
           db 19h                                           ;31 = Castle switch
           db 29h
           db 19h
           db 29h
           db 19h
           db 9eh,0ech
           db 1bh
           db 1ch
           db 1ch
           db 9fh,0c6h
           db 9eh,3ch
           db 11h
           db 1ah
           db 2ah
           db 12h                                           ;42 = Bishop switch
           db 5bh
           db 0a0h,1eh                                      ;44 = Queen switch
           db 0a0h,0e3h
           db 0a0h,7eh
           db 0a0h,0b4h
           db 89h
           db 8fh
           db 8fh
           db 8ah
           db 88h                                           ;41 HT 31

           db 0a0h,0b6h                                     ;queen 51
           db 0a0h,57h
           db 0a0h,6bh
           db 0a0h,0b2h
           db 8dh
           db 8ch
           db 88h                                           ;11 HT 2f

           db 0c0h,0fch,0ech,0cch,0ch                       ;bishop 5C
           db 0aah,0bch
           db 0b0h,98h
           db 0aah,48h
           db 83h
           db 8bh
           db 86h
           db 8ch
           db 88h                                           ;16 HT 31

           db 2bh                                           ;pawn 6C
           db 2ah
           db 5ah
           db 19h
           db 29h
           db 19h
           db 9eh,0ech
           db 1bh
           db 1ch
           db 1ch
           db 0c0h,3eh,0deh,26h,0d6h
           db 0ach,54h
           db 29h
           db 2ah
           db 1ah
           db 2ah
           db 1ah
           db 19h
           db 0a0h,38h
           db 8dh
           db 84h                                           ;28 HT 24

           db 9eh,0ech                                      ;castle 88
           db 1bh
           db 1ch
           db 1ch
           db 9fh,0c6h
           db 98h,1ch
           db 5bh
           db 5ch
           db 2ch
           db 5ch
           db 2ch
           db 5ch
           db 0a0h,67h
           db 0a0h,0a7h
           db 0a0h,9bh
           db 0a0h,92h
           db 81h                                           ;24 HT 29

           db 5bh                                           ;knight A0
           db 2bh
           db 2ah
           db 1ah
           db 9eh,0ech
           db 1bh
           db 1ch
           db 1ch
           db 9fh,0c6h
           db 1ah
           db 0c0h,0fch,5ch,0a6h,06h
           db 0c0h,0feh,2eh,0d3h,03h
           db 3ch
           db 5ch
           db 0e0h,0ffh,1eh,0a3h,03h
           db 0e0h,0ffh,0bh,46h,06h
           db 0e0h,7fh,17h,8ch,0ch
           db 0e0h,0bfh,0bh,31h,31h
           db 0e4h,7fh,07h,43h,43h
           db 0e6h,3fh,0bh,9dh,9dh
           db 0e3h,9fh,85h,7dh,61h
           db 0c3h,0bfh,8bh,0feh,82h
           db 0c6h,7fh,17h,0fdh,00h
           db 0c4h,0feh,0eh,0fbh,03h
           db 0c0h,0feh,2eh,9dh,65h
           db 0c0h,0fch,5ch,3ch,0dch
           db 0c0h,0f8h,38h,0e8h,68h
           db 0a6h,70h
           db 0ach,60h
           db 0b8h,0c0h
           db 88h                                   ;96 HT 2E
           
           ;256 bytes 134 lines

chess_2018A:
           rra                               ;test B/W BIT 0
           sbc a,a                           ;
           ld c,a                            ;set B/W component, Black=FF, White=00
continue:
           ld a,(ix+00h)                     ;get gfx byte
           inc ixl                           ;this INC must be here to avoid blanking repetition
test_line:
           add a,a                           ;test BIT 7
           ret z                             ;if 00 then its a blanking line, so RET

           push hl                           ;save the screen address for later
           push hl                           ;again
           push hl                           ;...and again!
           ld hl,0c000h                      ;initialise HL
           ld e,l                            ;E=00h
           ld b,0e0h                         ;ensure the counter is over max piece height.
           jr c,data_line                    ;if type '1' line then jump to data_line builder

standard_line:
           ld d,a                            ;save temp
           and 0fh                           ;mask counter 
           ld b,a                            ;B=counter
           ld a,c                            ;temp back into A
           xor d                             ;add in b/w component
           and 0f0h                          ;mask upper 4 bits F0h
           or 0ch                            ;add-in the '10'
           ld d,a                            ;data into D
           ld a,c                            ;bw byte into A
st_lp0:
           rlca                              ;propagate bw bit
           rr h                              ;
           rr l                              ;into HL
           ex de,hl                          ;swap sides
st_lp1:
           djnz st_lp0                       ;loop
           inc l                             ;set marker
           ex de,hl                          ;swap buffers
adjust:
           add hl,hl                         ;get bit
           rr d                              ;into
           rr e                              ;DE
           jr c,adjust                       ;repeat if marker found (BIT = 1)
           inc c                             ;test C
           jr z,print_line                   ;if it was 00(White) then swap buffers
           ex de,hl                          ;
adj_skp:
           jr print_line                     ;jump to printing line

data_line:
           ld d,(ix+00h)                     ;pre load D
           cp 1fh                            ;
           jr c,bit6_test                    ;
           inc ixl                           ;
bit6_test:
           add a,a                           ;test BIT 6
           jr nc,bit5_test                   ;next if '0'
long_line:
           ld l,a                            ;remainder of A into L - 6 bits
           and b                             ;mask upper 3 bits E0h
           add hl,hl                         ;
           add hl,hl                         ;
           add hl,hl                         ;
           ld e,a                            ;
ll_lp0:
           inc c                             ;B=FF to 00, W=00 to 01
           jr z,blk1                         ;if black, jump to get black2
wht1:
           ld d,(ix+00h)                     ;get White R
blk1:
           inc ix                            ;point to Black L
           jr z,blk2
wht2:
           ld h,(ix+01h)                     ;get Black L
           jr blk3
blk2:
           ld h,(ix+00h)
blk3:
           inc ixl
           inc ixl
           jr print_line
bit5_test:
           add a,a                           ;test BIT 5
           jr nc,bit4_test                   ;
bit5_set:
           add a,d                           ;get Left switch data in A then add it to Right buffer byte t ocreate the H byte
           jr bit4_res+1                     ;
bit4_test:
           add a,a                           ;test BIT 4
           jr nc,bit4_res                    ;if bit ='0' then the data for BWRL is in the 4 bits remaining in A
bit4_set:
           rra                               ;re-use bit to fill BIT 7, creating a left orientated mask
           and c                             ;mask with C BW byte to create 5 bit overlay mask of ccccc000
           xor d                             ;create the Black or White Left and Right buffer bytes
bit4_res:
           ld d,a                            ;load Right buffer
           ld h,a                            ;load Left buffer

print_line:
           ex (sp),hl                        ;put HL Left buffer on stack and retrieve screen address
           ex de,hl                          ;swap register pair, DE=screen address, HL=buffer
           ld c,80h                          ;bit mask R&L
right:
           call place_bit                    ;
           rrc c                             ;right bit mask move
           jr nc,ovr21                       ;
           inc e                             ;
ovr21:
           djnz right                        ;rpt if not 00
rst_left:
           ld c,80h
           pop hl                            ;LHS data retrieve

           pop de                            ;reset screen address
left:
           rlc c                             ;next left bit
           jr nc,ovr22                       ;
           dec e                             ;
ovr22:
           call place_bit                    ;
           djnz left                         ;repeat

           pop hl                            ;restore screen address

           ld a,ixl                          ;test for switch line
switch:
           cp 00h                            ;line to test for
           ret nz                            ;
set_jump:
           ex af,af'                         ;retrieve jump line
           ld ixl,a                          ;update IX
           ret                               ;finish  (33)
place_bit:
           ld a,h                            ;test whether HL contains 8000h
           or l                              ;
           sub 80h                           ;
           jr nz,ovr20                       ;
           ld h,a                            ;if so, zero the register and
           ld b,01h                          ;set the counter to finish on this pass
ovr20:
           add hl,hl                         ;get data bit
           sbc a,a                           ;
           ex de,hl                          ;swap to screen addr
           xor (hl)                          ;
           and c                             ;
           xor (hl)                          ;
           ld (hl),a                         ;place BIT
           ex de,hl                          ;swap back to data register
           ret                               ;RET 
                                             ;(149)
data_17:
           db 05h,07h,09h,0bh,0dh,09h,07h,05h
           db 03h,03h,03h,03h,03h,03h,03h,03h;01h(use BC op-code)          ;17 bytes
           
chess_builder:
           ld bc,00c0h                       ;start address of board
main_loop:
           ld ix,gfx_data                    ;IX reset address
           ld d,b                            ;D=00h
           dec b                             ;B=FFh
           ld a,(bc)                         ;get piece occupying square into A
           ld (main_call+1),a                ;store piece no.

get_piece_height:
           ld hl,piece_sizes-2               ;piece sizes & positions table base address
           rra                               ;find piece data
           ld b,a                            ;/2 into L
           add a,a                           ;X2
           add a,b                           ;+L = X3 = Trigger line, jump line, piece height
           add a,l                           ;
           ld l,a                            ;

           ld a,(hl)                      ;this byte determines which index line we make the jump at
           ld (switch+1),a                ;
           inc l                          ;
jump_to:
           ld a,(hl)                      ;
           ex af,af'                      ;this is the index line to jump to.
           inc l                          ;
set_height:
           ld b,(hl)                      ;this is the piece height

calc_square_addr:
           ld a,c
           ld hl,2822h                    ;HL=square 00 address
           ld e,l                         ;DE=0022h
csa_lp1:
           rra                            ;get lsb into carry
           jr nc,csa_ovr                  ;
           add hl,de                      ;
csa_ovr:
           rl e                           ;E x 2
           jr nc,csa_lp2                  ;
           ld e,1eh                       ;2nd part E value
csa_lp2:
           or a
           jr nz,csa_lp1                  ;loop if not found
csa_lp3:
           sla h                          ;H x 8
           jr nc,csa_lp3                  ;

           ld e,80h                       ;set the add line BIT mask to 80h

get_len:
           push de                        ;save line
           push bc                        ;save height + current square no.
current_square:
           ld a,c                         ;c=curent square
           and 09h                        ;
           jp pe,main_call                ;if white square, jump to main call
                                                  ;change to JP PO to effectively rotate the board
                                                  ;90 degrees.
new_calc_line:
           ld a,d                         ;D=current line
           sub 11h                        ;are we above the height of the board square?
           jr nc,main_call                ;if so, skip drawing the line

           adc a,d                        ;
           jr nc,ovr_e                    ;
           jr z,skp1                      ;
           dec a                          ;
skp1:
           cpl                            ;
ovr_e:
           and 0fh                        ;

           inc a                          ;
           ld b,a                         ;line length /2 in B
add_line_in:
           ld d,l                         ;save HL position
addl_lp1:
           rlc e                          ;next bit left
           jr nc,addl_ovr1                ;
           dec l                          ;update HL if theres a carry
addl_ovr1:
           djnz addl_lp1                  ;loop
draw_line:
           add a,a                        ;x2 to get line length
           ld b,a                         ;into B again
addl_lp2:
           ld a,(hl)                      ;
           or e                           ;
           ld (hl),a                      ;merge bit with screen content
           rrc e                          ;next right bit
           jr nc,addl_ovr2                ;
           inc l                          ;update HL if carry occurs
addl_ovr2:
           djnz addl_lp2                  ;

           ld l,d                         ;restore HL

main_call:
           ld a,00h                       ;piece occupying the current square
           or a                           ;is it empty?

           call nz,chess_2018A            ;call main build routine if a piece occupies the square
next_line_up:
           ld a,h                         ;fairly standard stuff
           dec h                          ;I'm sure we're all
           and 07h                        ;familiar with!
           jr nz,nlu_end                  ;
           ld a,l                         ;
           add a,0e0h                     ;
           ld l,a                         ;
           sbc a,a                        ;
           and 08h                        ;
           add a,h                        ;
           ld h,a                         ;
nlu_end:
           pop bc                         ;B=height C=current square
           pop de                         ;current line
           inc d                          ;

           djnz get_len                   ;inner loop for pieces
end_check_board:
           inc c                          ;next square
           jr nz,main_loop                ;repeat if needed

           ret                            ;ret

initialise_board:
           ld de,0ffc0h
           ld b,d
           ld c,d
           ld hl,data_17
ib_loop1:  
           ld a,(hl)
           dec a
           ld (bc),a
           ldi
           jr nz,ib_loop1
           dec e
           ld b,20h
ib_loop2:
           ld (de),a
           inc e
           djnz ib_loop2

           ret                   ;23 bytes (+17 data)

           piece_sizes:
           ;  SW  JL  HT
           db         11h                 ;square only - will use 2 previous bytes unimportant.
           db 28h,6ch,24h                 ;pawn
           db 31h,88h,29h                 ;castle
           db 28h,0a0h,2eh                ;knight
           db 42h,5ch,2fh                 ;bishop
           db 44h,51h,2fh                 ;queen
           db 28h,28h,31h                 ;king
:roll:

Oh yes, and RANDOMIZE USR 65338 to initialise the board unless you want it empty!

then RANDOMIZE USR 65208 to display it. Enjoy!
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

PaddyC13 wrote: Tue Jul 10, 2018 1:03 pm Nope, not lost interest at all. I would love to see a full blown Chess game created with it though.

Paddy
Way back a couple of years ago when I first began trying to compress the whole thing from the original sprites created in the early 90's, which were 4000 bytes alone!, I envisaged needing at least 400 bytes free out of 1k in order to produce some sort of basic GUI and Chess logic. Well, I do now seem to have reached that tipping point, so I think as soon as I get it below 600 bytes, then I will begin the next phase of trying to make it actually playable somehow.
User avatar
stupidget
Dynamite Dan
Posts: 1611
Joined: Wed Jan 24, 2018 2:09 pm
Location: Sunny Wolverhampton

Re: 3D Chess 2K18

Post by stupidget »

Quick question from a complete programming moron/numpty...what would I use to run the code you have posted?
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

I use conTEXT editor and Pasmo to edit/ assemble, however, try the handy pre-assembled .tap file at the link below;

https://dl.dropbox.com/s/7kbuk1nn60dw33 ... 1.tap?dl=1


You'll need to LOAD "" CODE though in this instance. ;)
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Update!

Now down to 607 bytes!
User avatar
Pegaz
Dynamite Dan
Posts: 1209
Joined: Mon Nov 13, 2017 1:44 pm

Re: 3D Chess 2K18

Post by Pegaz »

arkannoyed wrote: Tue Jul 10, 2018 1:18 pm
PaddyC13 wrote: Tue Jul 10, 2018 1:03 pm Nope, not lost interest at all. I would love to see a full blown Chess game created with it though.

Paddy
Way back a couple of years ago when I first began trying to compress the whole thing from the original sprites created in the early 90's, which were 4000 bytes alone!, I envisaged needing at least 400 bytes free out of 1k in order to produce some sort of basic GUI and Chess logic. Well, I do now seem to have reached that tipping point, so I think as soon as I get it below 600 bytes, then I will begin the next phase of trying to make it actually playable somehow.
Would 1k chess engine for zx81 be helpful?
This is really amazing piece of code.
http://users.ox.ac.uk/~uzdm0006/scans/1kchess/
http://users.ox.ac.uk/~uzdm0006/scans/1 ... assem.html
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

I've already been trying to gain a few pointers from that for some time now. It is a pretty useful size to kick off with, yes. I will probably work on some sort of GUI first to get it functioning, then worry about rules.
AndyC
Dynamite Dan
Posts: 1386
Joined: Mon Nov 13, 2017 5:12 am

Re: 3D Chess 2K18

Post by AndyC »

Certainly not lost interest. It's fascinating to see you continually squeeze this into less code and still somehow be making it faster. It's like watching magic happen.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Well, finally, I've done it!!!!

I've broken the 600 bytes barrier at last!

Now at 597 bytes!

Changes since last time;

shaved a bit more off the calculate square screen address routine.
added a second set of switch and jump line vectors and some code to allow it to function.

Adding the extra jump vectors has added 12 bytes to the jump table, but saved 27 bytes off the Graphics data making it now only 229 bytes. Thats 229 bytes for all of the pieces, Black and White.

Small alteration to the Knight just to allow the new functionality to work, but its not too noticeable.

I haven't actually touched the standard line building routine yet, and it still stands at 36 bytes, which just feels too big. When I can figure out a better and more efficient way of doing it, hopefully it'll get smaller by a few bytes too.

Just a bit of tidying up of the source before I can post it.
User avatar
ZXDunny
Manic Miner
Posts: 498
Joined: Tue Nov 14, 2017 3:45 pm

Re: 3D Chess 2K18

Post by ZXDunny »

Following like a madman here too, this is fascinating. Bit more of a write-up of what optimisations you make as you make them (with sources so we can follow along) would be gratefully received by the whole community, I'm sure.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

I agree, more detailed info on what gets changed is always a bonus, however, I tend to program in such a haphazard way, that its sometimes tricky. For instance, I've just spotted a way that I can save 1 byte. It would involve reversing all of the data. That may seem like a ridiculous thing to do to save 1 byte, however, the smaller it gets, the more significant that 1 byte becomes.

I've also saved an obvious byte in the main BIT placing routine, which is called to place every BIT of the sprite, so every pass is now -4TS too.

I am actively tidying up the source as I go. I've just actually found a neat optimisation thats saved another byte, so we're down to 595 bytes now.
:)
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: 3D Chess 2K18

Post by Kweepa »

The manager in me is saying "quit mucking around and write the chess logic".
The programmer in me is saying "go for 512 bytes!"
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Actually I have been increasingly frequent thoughts regarding 512 myself. I’ve no idea how I might achieve that though as we’re at 593, which is 81 bytes too big! :(
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: 3D Chess 2K18

Post by Ast A. Moore »

arkannoyed wrote: Sun Jul 15, 2018 9:06 am I’ve no idea how I might achieve that though as we’re at 593, which is 81 bytes too big! :(
Reduce the pieces’ dimensions. ;)
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

The one thing sacred is stayed true to the original design, so though that may save a few bytes, it’s not ethical! :D Also, the structure of the data means that the pieces would have to reduce to max 16 bits wide (from 22) and the height be probably 1/3rd. That would make them a bit tiddly looking really. Part of the challenge is maintaining the basic footprint of the pieces whilst reducing their size and the code to decipher and print them. I do have many tweeks and ideas still to implement, so the size should steadily reduce. 512 bytes might be possible if I were to not include the initialise the board routine in the overall size, which knocks 40 bytes off straight away. If the data is to get smaller, it’s going to have to do far more algorithm based graphics building, just maybe using the line number and a component to form a line of graphics data. The Standard line model already does that, with 3 bits for length, 4 bits of Pixel data, then puts it all together. Some of the data lines are also constructed in various ways from several components. So far there are 5 distinct line types of 1,1,2,2 or 5 bytes. 5 bytes are obviously the longest and more complex lines, but there are actually only 22 of those anyway. There are patterns even in those which could allow further data reduction, but at the expense of more program code, so currently no point pursuing that avenue.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

A lot of re-organising to achieve a bit more size reduction. Also a neat way to store the pieces vector table position, which saved 5 bytes alone.

Now at 588 bytes

Still plenty to do and I really am making good progress on commenting the source at last!
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Some decent changes this morning, and now at 586 bytes

I'm now struggling to find any further improvements :?

If I'm going to achieve that 512 bytes magic number, (586 -40 bytes (initialise board routine and data) = 546 - 512 =34 bytes)

Then I still need to save a further 34 bytes, which is looking rather far away.
User avatar
Pegaz
Dynamite Dan
Posts: 1209
Joined: Mon Nov 13, 2017 1:44 pm

Re: 3D Chess 2K18

Post by Pegaz »

I think you've done a great job so far and maybe it's time to start adding a decent (also a memory-efficient) chess engine.
I guess the optimization of board routines is possible later if you find more space for that.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: 3D Chess 2K18

Post by arkannoyed »

Optimization has to always be done keeping in mind the fact that somehow, some kind of GUI will have to be integrated into it at some point. Once I achieve the best balance of speed and size (hopefully very small!) the routine will then start to grow in size again incorporating several elements such as piece and square selection. once that all works as efficiently as it can, then it will be time to add some kind of logic and error checking into the mix. Fortunately, this iteration seems to allow a lot more flexibility to add new features without it getting all grumpy about it. Thats more by luck than design!
I still intend another redesign of the graphics, as I think there are a few areas that might benefit from alterations, helping a more crowded board appear less cluttered. Certain formations of graphics print faster than others, and can be encoded in less space. The bases of the pieces are all common, but look a little heavy. Shaving just 1 line off them could save 5 bytes! Not huge, but maybe significant in the end.

The nice thing about it is that it all feels very stable as it is, not using registers that it shouldn't, and not creating any huge buffers in memory. Its so efficient now that its even almost relocatable.

..And now 585 bytes! :P
Post Reply