Jump to content

Is ther a way i not to use stacks in this tictactoe code

- - - - -

  • Please log in to reply
3 replies to this topic

#1
dev_JC

dev_JC

    Newbie

  • Members
  • Pip
  • 3 posts
attached is a tictactoe code my code partner gave me,

IS THERE A WAY, that I can convert this to a CODE that does not use stack, or use Array instead.

can u help me start with the RE-COde process.PLS.

Any help will do,.THANKS IN ADVANCE.

Attached Files

  • Attached File  x86.asm   18.45K   37 downloads


#2
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,252 posts
  • Location:C:\Countries\US
Sure. You'll just have to make your own version of the game_state() function (lines 276 through 351, in the file you provided, is what it currently is; line numbers in the file I have are different, though).

I went over some (well, it's a little too long, for me to go over everything in the file) stuff in the file. There are some inefficiencies, which should still work, but the biggest mistake I noticed was in the epilogues; this:
pop ebp 

ret 
should be this:
mov esp, ebp 

pop ebp 

ret 

Other than that, here's the text from the file that I commented in:
%include "asm_io.inc"


%define FALSE 0

%define TRUE 1


;for comparison

%define PLAYER 0

%define COMP 1

%define UNOCCUPIED 2

;Game state

%define ONGOING 0

%define DRAWN 1

%define PLAYER_WON 2

%define COMP_WON 3

;for spacing

%define NL 10

%define TAB 9


segment .data

Title db  "This is the Tic Tac Toe Game!", NL, 0


segment .text

    global asm_main


asm_main:

    

	mov    eax,Title

	call   print_string


	call    prompt_difficulty


	mov     esi, eax 			;difficulty choosen is moved to esi

	

	call    clear_screen			; clear the screen from the instructions


	xor     ebx, ebx 			; num_games = 0	;number of games already played. Used to determine who should go first


m_game_loop:

    

	mov     ecx, ebx			;ecx = first

	and     ecx, 0x1 			; ecx = ebx % 2;	;for change of player or computer will input first


	;; okay, so it looks like play_game() has two arguments, player (0 or 1) and difficulty (1 or 2) 

	push    esi				;push esi = depende sa difficulty na gn choose nya

	push    ecx				;push ecx = depende kung pampila na nga game kung round 1, una user, then bulos bulos lng

	call    play_game

	add     esp, 8				;clear out ang stack

	;; it's also a cdecl function, rather than stdcall 


	;; why not just use 'inc ebx' ? 

	add     ebx, 1				; INCREMENT EBX or num_games


	;Loop AGAIN TO PLAY. (DRI TA DAPAT MA BUTANG SCANNER na Q to quit)


	jmp     m_game_loop			


	; should never be reached, but for the sake of completeness...


;; what? but you don't even have a prologue for this 'start' code, how come you have an epilogue? 

	xor     eax, eax

	pop     ebp

	ret					; EXIT


;*------------------------------------CHOOSE OF DIFFICULTY-----------------------------------------------------------*

segment .data

; strings

level_msg1    db    "Select a difficulty -", NL, 0

level_msg2 db    TAB, "1. God. The computer plays perfect games. ", NL, TAB, "   You have no mathematical chance of winning or maybe there is.", NL, 0

level_msg3 db    TAB, "2. Devil. Thought God mode was too hard? Now try to lose :).", NL, 0

level_msg4 db    "choice? ", 0

pd_str5 db    "Enter a number between 1 and 2 inclusive.", NL, "? ", 0

pd_scanf_format_str    db    "%d", 0


segment	.bss

pd_rtn	resd	1


segment .text

    global prompt_difficulty

    extern printf, scanf, getchar


prompt_difficulty:

    

    ; print out the lines for difficulty level


    mov    eax,level_msg1

    call    print_string

    mov    eax,level_msg2

    call    print_string

    mov    eax,level_msg3

    call    print_string

    mov    eax,level_msg4

    call    print_string

    

    ; get the choice from the user

pd_scanf_loop:

    

	call	read_int

	mov	dword [pd_rtn],eax

    

pd_check_range: ; has to be 1 or 2

;; why not just compare EAX to 1 and 2? 

    cmp     dword [pd_rtn], 1

    jz      pd_out_of_scanf_loop

    cmp     dword [pd_rtn], 2

    jz      pd_out_of_scanf_loop


    mov    eax,pd_str5

    call    print_string

    jmp     pd_scanf_loop

    

pd_out_of_scanf_loop: 

;; come on, seriously? EAX is already equal to [pd_rtn] 

    mov     eax, dword [pd_rtn]

    

    ; epilog

    ret

;*-----------------------------------------------------------------------------------------------*

;*--------------------------------------PLAY GAME---------------------------------------------------------*

segment .data

; strings

pg_str1 db  "The game was drawn.", NL, 0

pg_str2 db  "Computer won :(", NL, 0

pg_str3 db  "OMG!!Congratulations! You won!", NL, 0


segment .text

    global play_game

   

%define pg_first [ebp+8]

%define pg_difficulty [ebp+12]


; stack variables

; ebp-36 to ebp-4


%define pg_board_array [ebp-36]

%define pg_turn [ebp-40]

%define pg_state [ebp-44]

%define pg_player_symbol [ebp-48]

%define pg_comp_symbol [ebp-52]

;%define pg_i [ebp-56]

%define pg_move [ebp-60]


play_game:

    

    ; prolog

    push    ebp

    mov     ebp, esp


    sub     esp, 60

    

    push    ebx

    push    edi

    

    mov     eax, pg_first		;turn = ECX (first);

    mov     dword pg_turn, eax


    mov     dword pg_state, ONGOING	;state = ONGOING(0)

    lea     ebx, pg_board_array		;board_array[ebx]

    

    cmp     dword pg_first, PLAYER

    jz      pg_player_first			;jmp to ang symbols if user ang una

    mov     dword pg_player_symbol, 'X'		;kapag PC naman una, amu ni ang symbols

    mov     dword pg_comp_symbol, 'O'

    jmp     pg_symbols_choosing_end

    

pg_player_first:

    

    mov     dword pg_player_symbol, 'O'

    mov     dword pg_comp_symbol, 'X'


					;Tapus na ang pagpili sng symbols

pg_symbols_choosing_end:			

					;so ma initialize ta anay na wala pa unod ang ang board

	

	;for (edi = 0; edi < 9; ++edi) {

	;	board[edi] = UNOCCUPIED;}	

	; initialize the board

	cld

	mov     edi, ebx

	mov     ecx, 9

	mov     eax, UNOCCUPIED

	rep stosd

    

pg_game_loop:

					

    push    ebx				;push naman kung ikapila na nga game EBX==NUmgames

    call    game_state			;b4 mag proceed check anay if may daug na

    pop     ecx				;OKAY NATAPUS NA CHECK

    

    mov     pg_state, eax		; so kung anu man result dd2 gna if 0,1,2,3

    cmp     eax, ONGOING		; compare ta sya sa ONGOING(2)

    jnz     pg_game_loop_end		;pag dili sya ongoing, ma END na ang ROUND

    

    cmp     dword pg_turn, PLAYER	;proceed ta d if ONGOING sya GYAPUN

    jnz     pg_game_loop_comp_turn	; Sa round 1 syempre ma una gd ang player kay ang value sng pg_turn ta diri is 0, kasi wala pa ma increment

    

    ; it's the player's turn

    push    dword pg_comp_symbol

    push    dword pg_player_symbol

    push    ebx

    call    prompt_move			;CALL PROMPT_MOVE, DIRI MA MAGALAIN ANG BOARD DIRI NAMAN DAUN MA PRINT SNG GAME BOARD

    add     esp, 12

    

    mov     dword [ebx + eax*4], PLAYER

    

    call    clear_screen

    jmp     pg_game_loop_endif

   

pg_game_loop_comp_turn:


    push    dword pg_difficulty

    push    ebx

    call    comp_move

    add     esp, 8

    

    mov     dword [ebx + eax*4], COMP


pg_game_loop_endif:


    xor     dword pg_turn, 1


    jmp     pg_game_loop

    

pg_game_loop_end:


    call    clear_screen

    

    push    dword FALSE

    push    dword pg_comp_symbol

    push    dword pg_player_symbol

    push    ebx

    call    print_board

    add     esp, 16

    

    cmp     dword pg_state, COMP_WON			;check if PC ang winner

    jnz     pg_declare_result_check2			;

    mov    eax,pg_str2

    call    print_string

    jmp     pg_declare_result_end

    

pg_declare_result_check2:


    cmp     dword pg_state, PLAYER_WON			;check liwat if USER na gd man ang winner

    jnz     pg_declare_result_draw

    mov    eax,pg_str3

    call    print_string

    jmp     pg_declare_result_end

    

pg_declare_result_draw:


    mov    eax,pg_str1

    call    print_string


pg_declare_result_end:


    ; epilog

    pop     edi

    pop     ebx

    add     esp, 60

    

    pop     ebp    

    ret


;*----------------------------------------GAME STATE-------------------------------------------------------*    

segment .data

;       { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, /* horizontal */

;        { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, /* vertical */

;        { 0, 4, 8 }, { 2, 4, 6 } /* diagonals */


gs_groups dd    0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 3, 6, 1, 4, 7, 2, 5, 8, 0, 4, 8, 2, 4, 6  


segment .text

    global game_state

    

; FUNCTION int game_state(int *board)

; determines the state of the game (PLAYER_WON, COMP_WON, or DRAWN)

; PARAMETERS board ([ebp+8]) - the current board

; RETURN the state of the game


%define gs_board [ebp+8]


game_state:


    ; prolog

    push    ebp

    mov     ebp, esp

    

    push    edi

    push    esi

    

    mov     edi, gs_board

    mov     esi, gs_groups

    mov     ecx, 8

    

gs_combo_loop:

    

    mov     edx, [esi]    		;ang ESI amu na sya ang DIFFICULTY dbala

;; what's EDX supposed to be at this point? 

    mov     eax, [edi + edx*4]		;VEN BULIG D DANAY D KO MA FIGURE OUT ja

    cmp     eax, UNOCCUPIED		;UNOCCUPIED = 2

    jz      gs_combo_loop_continue	;continue lng, we won't get a win by UNOCCUPIED

    

    mov     edx, [esi+4]

    cmp     [edi + edx*4], eax

    jnz     gs_combo_loop_continue

    

    mov     edx, [esi+8]

    cmp     [edi + edx*4], eax

    jnz     gs_combo_loop_continue

    					;dapat ma satisfy nya na ang conditions

					;para mabalan na may winner

    					; we have a winner!

			

					;if (board[combinations[i][0]] == PLAYER 

					;  && board[combinations[i][1]] == PLAYER 

					;  && board[combinations[i][2]] == PLAYER) {

					;return PLAYER_WON;	


					;else if (board[combinations[i][0]] == COMP 

					;  && board[combinations[i][1]] == COMP 

					;  && board[combinations[i][2]] == COMP) {

					;return COMP_WON;


    cmp     eax, PLAYER

    jnz     gs_determine_winner_comp

    mov     eax, PLAYER_WON		;eax = 2

    jmp     gs_epilog			;go to ret

gs_determine_winner_comp:

    mov     eax, COMP_WON		;eax = 3

    jmp     gs_epilog			;goto ret


gs_combo_loop_continue:			

    add     esi, 12

    loop    gs_combo_loop		;ga liwat2x sya yata check

    


; drawn or ongoing


    cld

    mov     eax, UNOCCUPIED			

    mov     ecx, 9

    repne scasd

    

    jnz     gs_not_found

    mov     eax, ONGOING		;set value of EAX = 2, kay wala pa may nagdaug, so continue gyapun

    jmp     gs_epilog

    

gs_not_found:


    mov     eax, DRAWN

    

gs_epilog:


    pop     esi

    pop     edi


;; what about the 'mov esp, ebp' right before this ?!!!! 

    pop     ebp

    ret


;*-------------------------------------------PROMPT MOVE----------------------------------------------------*

segment .data

pm_prompt   db  "Your move: ", 0

pm_prompt_err   db  "Enter the number of an empty square.", NL, 0

pm_format   db  "%d", 0


segment .text

    global prompt_move

    

; FUNCTION int prompt_move(int *board, int player_symbol, int comp_symbol)

; prompt a legal move (for the board) from the user

; PARAMETERS board ([ebp+8]) - the current board

;            player_symbol ([ebp+12]) - symbol for the player

;            comp_symbol ([ebp+16]) - symbol for the comp

; RETURN the move entered


%define pm_board [ebp+8]

%define pm_player_symbol [ebp+12]

%define pm_comp_symbol [ebp+16]


%define pm_move [ebp-4]


prompt_move:

    

    push    ebp

    mov     ebp, esp

    

    sub     esp, 4

    

    ; print out the board first


    push    dword TRUE

    push    dword pm_comp_symbol

    push    dword pm_player_symbol

    push    dword pm_board

    call    print_board				;PRINT MUNA ANG GAMEBOARD

    add     esp, 16

    

    jmp     pm_input_loop

    

pm_input_loop_err:


    push    pm_prompt_err

    call    printf

    pop     ecx

    

pm_input_loop:

    

    push    pm_prompt

    call    printf

    pop     ecx

    

    lea     eax, pm_move

    push    eax

    push    pm_format

    call    scanf

    add     esp, 8

    

    cmp     eax, 1

    jz      pm_input_loop_check_range

    jmp     pm_input_loop_cleanup


pm_input_loop_check_range:

    

    cmp     dword pm_move, 9

    jg      pm_input_loop_err

    cmp     dword pm_move, 1

    jl      pm_input_loop_err

    

    mov     eax, pm_move

    mov     edx, pm_board

    sub     eax, 1

    cmp     dword [edx + eax*4], UNOCCUPIED

    jnz     pm_input_loop_err

    

    jmp     pm_input_loop_out


pm_input_loop_cleanup:


    call    getchar

    cmp     eax, NL

    jnz     pm_input_loop_cleanup

    

    jmp     pm_input_loop_err


pm_input_loop_out:


    mov     eax, pm_move

    sub     eax, 1

    

    ; epilog    

    add     esp, 4

    pop     ebp

    ret

;*---------------------------------------COMP_MOVE------------------------------------*

segment .text

    global comp_move

        

; FUNCTION int comp_move(int *board, int difficulty)

; generate a move for the computer player, for difficulty level specified

; PARAMETERS board ([ebp+8]) - the current board

;            difficulty ([ebp+12]) - the difficulty level (1 or 2)

; RETURN the move to be made


%define cm_board [ebp+8]

%define cm_difficulty [ebp+12]


%define cm_best_score [ebp-4]

%define cm_best_move [ebp-8]


comp_move:


    ; prolog

    push    ebp

    mov     ebp, esp

    

    sub     esp, 8

    

    ; we need to preserve ebx

    push    ebx

    

    mov     ebx, cm_board

    

    ; initialize the variables

    mov     dword cm_best_score, -999

    

    mov     ecx, 9

    xor     edx, edx

    

cm_loop:


    cmp     dword [ebx + edx*4], UNOCCUPIED

    jnz     cm_loop_continue

    

    mov     dword [ebx + edx*4], COMP

    

    push    ecx

    push    edx

    

    push    dword cm_difficulty

    push    dword PLAYER

    push    ebx

    call    minimax

    add     esp, 12

    

    pop     edx

    pop     ecx

    

    neg     eax

    

    mov     dword [ebx + edx*4], UNOCCUPIED

    

    cmp     eax, cm_best_score

    jle     cm_loop_continue

    

    mov     cm_best_score, eax

    mov     cm_best_move, edx

    

cm_loop_continue:


    add     edx, 1

    loop    cm_loop

    mov     eax, cm_best_move

    jmp     cm_epilog


cm_epilog:


    pop     ebx    

    

    add     esp, 8    

    pop     ebp

    ret

;*-----------------------------------------MINIMAX--------------------------------

segment .data

; memory jump table!! =D

mm_jump_table   dd  mm_ongoing, mm_drawn, mm_player_won, mm_comp_won


segment .text

    global minimax

        

; FUNCTION int minimax(int *board, int stm, int difficulty)

; evaluate the current board in stm's perspective

;        0 means draw

;        10 means win on board

;        9 means win in 1

;        ...

;        -10 means loss on board

;        -9 means loss in 1

;        ...

; PARAMETERS board ([ebp+8]) - the current board

;            stm ([ebp+12]) - side to move

;            difficulty ([ebp+16]) - difficulty level (1 or 2)

; RETURN the score


%define mm_board [ebp+8]

%define mm_stm [ebp+12]

%define mm_difficulty [ebp+16]


%define mm_bestmove [ebp-4]

%define mm_bestscore [ebp-8]


minimax:


    ; prolog

    

    push    ebp

    mov     ebp, esp

    

    sub     esp, 8

    

    ; we need to preserve ebx

    push    ebx

    

    mov     ebx, mm_board

    mov     dword mm_bestscore, -999


    ; call game_state

    push    ebx    

    call    game_state

    pop     ecx

    

    jmp     [mm_jump_table + eax*4]

    

mm_ongoing:


    mov     ecx, 9

    xor     edx, edx


mm_recurse_loop:

    

    cmp     dword [ebx + edx*4], UNOCCUPIED

    jnz     mm_recurse_loop_continue

    

    push    ecx

    push    edx

    

    mov     eax, mm_stm

    mov     dword [ebx + edx*4], eax

    

    push    dword mm_difficulty

    

    xor     dword mm_stm, 1    

    push    dword mm_stm    

    xor     dword mm_stm, 1

    

    push    ebx

    

    call    minimax

    

    add     esp, 12

    

    pop     edx

    pop     ecx

    

    neg     eax

    

    mov     dword [ebx + edx*4], UNOCCUPIED

    

    cmp     eax, mm_bestscore

    

    jle     mm_recurse_loop_continue

    

    mov     mm_bestscore, eax

    mov     mm_bestmove, edx    


mm_recurse_loop_continue:


    add     edx, 1

    loop    mm_recurse_loop

    

    cmp     dword mm_bestscore, 0

    jle     mm_ongoing_le

    

    sub     dword mm_bestscore, 1

    jmp     mm_ongoing_end

    

mm_ongoing_le:


    cmp     dword mm_bestscore, 0

    jz      mm_ongoing_end

    

    add     dword mm_bestscore, 1


mm_ongoing_end:


    mov     eax, mm_bestscore

    jmp     mm_epilog

    

mm_drawn:


    xor     eax, eax

    jmp     mm_epilog


mm_player_won:


    ; if the sum of stm and difficulty is odd, return 10, else -10

    

    mov     eax, dword mm_stm

    add     eax, mm_difficulty

    test    eax, 0x1

    jnz     mm_return_10

    jmp     mm_return_n10


mm_comp_won:    

    

    ; if the sum of stm and difficulty is even, return 10, else -10

    

    mov     eax, dword mm_stm

    add     eax, mm_difficulty

    test    eax, 0x1

    jz      mm_return_10

    jmp     mm_return_n10


mm_return_10:


    mov     eax, 10

    jmp     mm_epilog


mm_return_n10:


    mov     eax, -10

    jmp     mm_epilog


mm_epilog:


    pop     ebx

    

    add     esp, 8

    

    pop     ebp

    ret


;----------------------------------------'PRINT BOARD'-------------------------------------

segment .data

pb_f_beg   db  NL, NL, NL, NL, 0

pb_f_val   db  TAB, " %c | %c | %c", NL, 0

pb_f_sep   db  TAB, "------------", NL, 0

pb_f_end   db  NL, 0


segment .text

    global print_board

 

; FUNCTION void print_board(int *board, int player_symbol, int comp_symbol, int print_numbers)

; print the board to stdout in a human readable format

; PARAMETERS board ([ebp+8]) - the current board

;            player_symbol ([ebp+12]) - the symbol used to represent the player

;            comp_symbol ([ebp+16]) - the symbol used to represent the computer

;            print_numbers ([ebp+20]) - boolean. whether numbers should be used for unoccupied squares

; RETURN none


%define pb_board [ebp+8]

%define pb_player_symbol [ebp+12]

%define pb_comp_symbol [ebp+16]

%define pb_print_numbers [ebp+20]


%define pb_print_table [ebp-36]


print_board:

    

    ;prolog 

    push    ebp

    mov     ebp, esp

    

    sub     esp, 36

    

    push    edi

    push    esi

    

    lea     edi, pb_print_table

    mov     esi, pb_board

    

    mov     ecx, 9			;serves as the counter

    xor     edx, edx			;edx = 0


pb_loop:

	;char print_bd[9]

	;int i

	;for (i = 0; i < 9; ++i) {

	;	if (board[i] == UNOCCUPIED) {

	;		if (print_numbers) {

	;			print_bd[i] = i + '1';

	;		} else {

	;			print_bd[i] = ' ';

	;		}

	;	} else if (board[i] == PLAYER) {

	;		print_bd[i] = player_symbol;

	;	} else if (board[i] == COMP) {

	;		print_bd[i] = comp_symbol;

	;	}

	;}


    cmp     dword [esi + edx*4], UNOCCUPIED

    jnz     pb_loop_occupied

    

    cmp     dword pb_print_numbers, 0

    jnz     pb_loop_print_numbers

    

    mov     dword [edi + edx*4], ' '

    jmp     pb_loop_continue

    

pb_loop_print_numbers:


    mov     dword [edi + edx*4], '1'

    add     dword [edi + edx*4], edx

    jmp     pb_loop_continue


pb_loop_occupied:


    cmp     dword [esi + edx*4], PLAYER

    jnz     pb_loop_comp

    

    mov     eax, pb_player_symbol

    mov     dword [edi + edx*4], eax

    jmp     pb_loop_continue


pb_loop_comp:


    mov     eax, pb_comp_symbol

    mov     dword [edi + edx*4], eax

    jmp     pb_loop_continue


pb_loop_continue:

    

    add     edx, 1

    loop    pb_loop

    

pb_loop_end:

    

    push    pb_f_beg

    call    printf

    

    push    dword [edi + 8]

    push    dword [edi + 4]

    push    dword [edi + 0]

    push    pb_f_val

    call    printf

    

    push    pb_f_sep

    call    printf

    

    push    dword [edi + 20]

    push    dword [edi + 16]

    push    dword [edi + 12]

    push    pb_f_val

    call    printf

    

    push    pb_f_sep

    call    printf

    

    push    dword [edi + 32]

    push    dword [edi + 28]

    push    dword [edi + 24]

    push    pb_f_val

    call    printf

    

    push    pb_f_end

    call    printf

    

    add     esp, 64

    

    pop     esi

    pop     edi

    

    add     esp, 36

    pop     ebp

    ret

;----------------------------------------------'SYSTEM CLEAR'---------------------------------    

segment .data

cs_cmd      db  "clear", 0

;cs_cmd     db  "cls", 0

; use the second one for Windows


segment .text

    global clear_screen

    extern system

 

; FUNCTION void clear_screen()

; clear the screen using OS functions

; PARAMETERS none

; RETURN none


clear_screen:


    ; prolog

    push    ebp

    mov     ebp, esp

    

    push    cs_cmd

    call    system

    pop     ecx

    

    pop     ebp

    ret


Note, however, that all the 'je' and 'jne' instructions are 'jz' and 'jnz' , in the text above. That's because to go over it, I had to do such a change, because I'm used to working with 'jz' and 'jnz' . In case you're wondering, 'je' is a mnemonic synonym for 'jz' , and 'jne' is a mnemonic synonym for 'jnz' , which means that it doesn't matter which you use - the assembler will still convert either ('je' or 'jz' , for example) to the same opcode (0x74, and then a byte that specifies the relative-to-the-next-instruction offset of where to jump).
For example, both instructions in this code:
je one 

jz one 


one: 
assemble to the same opcode, as can be seen, when disassembled:
00000000  7402              jz 0x4

00000002  7400              jz 0x4
(at offset 0, 'jz 4' assembles to 0x74 (which is JZ), relative 0x02; at offset 2, 'jz 4' assembles to 0x74, relative 0x00)


But yeah, you would probably want to code your own version of game_state(), and according to these defines:
%define ONGOING 0

%define DRAWN 1

%define PLAYER_WON 2

%define COMP_WON 3
return 0, 1, 2, or 3, depending on what the board has. And each slot in the board (obviously) should have one of these values:
%define PLAYER 0

%define COMP 1

%define UNOCCUPIED 2
(0, 1, or 2)

game_state() would probably have 1 parameter, which should be the pointer to the board array. The board array seems to be an array of integers (4 bytes per integer), with 9 elements. I would imagine you'd have to have the computer go ahead and check to see whether any one user has 3 slots in a row; the algorithm you use is up to you, but it might help if you sit down and plan the algorithm (algorithm doesn't mean code; algorithm is 'how' you do something), before getting to the actual code.

#3
dev_JC

dev_JC

    Newbie

  • Members
  • Pip
  • 3 posts
Thanks man, I'm starting to recode this one without using stacks but do you have any idea on how will I check if there is already a 3 in a row combination??

to tell you the truth I cant even understand this code, my friend showed it to me,yes this is our project,but I want it to be simpler, and I'm having a hard time.

#4
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,252 posts
  • Location:C:\Countries\US
Well, first of all, you have a 9-element, one-dimensional, array. That's not bad, because there's more than one way to do it and you don't have to use two-dimensional arrays, if you don't want to.

So if you have this tic-tac-toe board:
a b c 

d e f 

g h i 

Then the array would consist of:
[a, b, c, d, e, f, g, h, i] 

You could start by checking if elements [1 and 2 and 3] or [4 and 5 and 6] or [7 and 8 and 9] are equal. Then you could check elements [1 and 4 and 7] or ... etc.

A more efficient, I think, idea that I got is check from the square last updated. For example, the user just clicked the square 1x1; you either start from 1x1 or from some square beside it, whichever is closer to the edge; then you compare that value to either 1x1 or the square beside 1x1, whichever is further away from the edge; then you compare that to the square that's opposite both of the squares you just compared; if any one of them is not equal, then it's not a 3-in-a-row match.

Okay, back to the 1x1.
if [1x1] == [2x1] and [1x1] == [3x1] then true
if [1x1] == [2x2] and [1x1] == [3x3] then true
if [1x1] == [1x2] and [1x1] == [1x3] then true
all other cases, false

Something like that. But if the user clicks 2x1 then you'll have to do something more like this:
if [2x1] == [1x1] and [2x1] == [3x1] then true
if [2x1] == [2x2] and [2x1] == [2x3] then true
all other cases, false

Or if 2x2 is clicked:
if [2x2] == [1x1] and [2x2] == [3x3] then true
if [2x2] == [2x1] and [2x2] == [2x3] then true
if [2x2] == [3x1] and [2x2] == [1x3] then true
if [2x2] == [1x2] and [2x2] == [3x2] then true
all other cases, false

It should be similar for other squares, based on these three checks. If it's either 2x1 or 1x2 or 3x2 or 2x3 then you only have to compare two rows. If it's 1x1 or 3x1 or 1x3 or 3x3 then you'll have to compare three rows. Otherwise, if it's 2x2 (center), then you'll have to compare four rows. (They're not really rows rows, but ... whatever they're called.)

* * *

When coding that stuff - in case I haven't told you already - , you can try writing the algorithms first, before getting to the actual code; especially with assembly language, it could be helpful.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users