I am making the game "Connect Four". I have a square board which is 4x4. For each tile on the board I have to draw a disc (squre shaped) which has an x value and a y value. The problem is that I have to make 32 variables or a lot of procedures which change the two variables all the time but these options seem very unefficient and the code would be very long. If you have any suggestions of how to it more efficient, please tell.
*Note - I am using x86 Assembly and TASM Here is the code:
proc CheckPlayer1Number
mov ah, 7
int 21h
cmp al, 31h
je CheckColumn1
jmp CheckPlayer1Number
endp CheckPlayer1Number
proc CheckColumn1
cmp [FirstColumnArray], 0
je ChangeColumnNumber1
endp CheckColumn1
proc ChangeColumnNumber1
inc [FirstColumnArray]
mov [Player1Drawx], 25h
mov [Player1Drawy], 87h
jmp DrawPlayer1Disc
endp ChangeColumnNumber1
DrawPlayer1Loop:
mov bh,0h
mov cx,[Player1Drawx]
mov dx,[Player1Drawy]
mov al,[player1disccolor]
mov ah,0ch
int 10h
inc [Player1Drawx]
cmp cx, [Player1Drawx + 14h]
jl DrawPlayer1Loop
DrawPlayer1Disc:
mov bh, 0h
inc [Player1Drawy]
cmp dx, [Player1Drawy + 14h]
jl DrawPlayer1Loop
I have only programmed a bit just to see if the code works.
Thanks for the help.
Use arrays instead of separate variables? Like an array of four arrays of four (x,y) values. All you need then is the base address of the array, and from that you can get all elements of the arrays through offsets.
In C it would be something like
struct Disc
{
int x;
int y;
};
struct Disc array[4][4];
C is a very low-level language, close "to the metal", and could in some cases (especially early in its history) be seen as a very advanced macro-assembler.
An array in C is a sequential and contiguous chunk of memory, each element following the other, so it's very easy to calculate the offsets to a specific element in the array. In fact that's what the C compiler does for you, and it's also the reason that array indexes is starting with zero in C and not 1 like in many other high-level languages from the same era.
For a simple array like e.g.
int a[4];
the offset to the each element in the array is the index multiplied by the size of the data. To get element 0 (i.e. a[0]
) you do 0 * sizeof(int)
, to get the second element you do 1 * sizeof(int)
.
Now to take the array of arrays of structures I showed above you use the same principle to calculate the offsets from the beginning of the memory: Index multiplied by element size.
If we start backwards, the structure is two int
members, which on a typical 32-bit machine is 8 bytes in total (each member being a 4 byte (32 bit) integer, two members). That means that the inner array is 8 bytes time 4 elements, or 32 bytes. To get a specific element in the array you multiply the index with 8 (size of structure) and add it as an offset to the start of the array.
For the outer array every element is 32 bytes (each element is an array of 4 structures), which means the total size of array
shown above is 128 bytes. To get an element in that array you multiply the zero-based index with 32.
Using the above, the way to get to the structure at array[i][j]
(for an arbitrary but in-range value of i
and j
) you get the base address of array
, add i * 32
to get to the inner array, then add j * 4
to get to the actual structure. In pseudo-code (not real C) it would look like
structure = array + i * 32 + j * 4
That give you the address to a specific structure. Now to get the members of the structure is just the same. The member x
is at offset 0 and the member y
is at offset 4 (the size of the previous member(s)). Again with the pseudo-code:
x = structure
y = structure + 4
So to handle your board you only need three "variables": The base address of the outer array, and the indexes i
and j
.
My x86 assembly is rusty, it was a long time ago I used it, but calculating the offsets and moving the correct structure variables into a register is easy IIRC.