Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

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

stack

  • Please log in to reply
3 replies to this topic

#1 dev_JC

dev_JC

    CC Lurker

  • Just Joined
  • Pip
  • 3 posts

Posted 30 September 2011 - 05:49 AM

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.45KB   148 downloads

  • 0

#2 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1311 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 30 September 2011 - 09:44 PM

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.
  • 0

#3 dev_JC

dev_JC

    CC Lurker

  • Just Joined
  • Pip
  • 3 posts

Posted 02 October 2011 - 01:03 AM

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.
  • 0

#4 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1311 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 03 October 2011 - 05:31 PM

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.
  • 0





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download