The MASM Forum

Projects => Game Development => Topic started by: zedd151 on May 01, 2018, 10:30:57 AM

Title: Four in a Row - R&D
Post by: zedd151 on May 01, 2018, 10:30:57 AM
I have started doing research on developing a game similar to connect 4. I will call mine 4-in-line.

As I still do not have the capacity to test any code yet, I am doing other research into algorithms and analysis of the game.

Some interesting material is found here:

 pokamis.com  (http://www.pomakis.com/c4/)
such as
 Masters Thesis by Victor Allis - pdf download  (http://www.informatik.uni-trier.de/~fernau/DSL0607/Masterthesis-Viergewinnt.pdf)

 Article about Connect-4 by James D. Allen (http://www.pomakis.com/c4/expert_play.html)

I am search for better approaches in determining next move. I have a lot of reading to do, I thought I would share this here as it is relevent to Game Development.   :biggrin:


edit == Changed thread title to reflect a name for my game that I like much better.
Title: Re: zedds "4-in-line" research
Post by: Lonewolff on May 01, 2018, 10:36:29 AM
Nice! Looking forward to seeing what you do.  8)
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 01, 2018, 10:51:50 AM
Nice! Looking forward to seeing what you do.  8)

I have some ideas, even some sloppyy pseudo code already.  Hard to write code without the proper tools.

The first version will most likely be console based.
Title: Re: zedds "4-in-line" research
Post by: daydreamer on May 02, 2018, 03:25:33 AM
I seen 4 in a line code earlier, from a computer Magazine showing recursive proc that checks several moves ahead,but it also showed a 3d version of 4 in a line

Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 02, 2018, 04:14:01 AM
Hi daydreamer

My version will allow the human player to win 50 or 60 percent of the time.  Possibly using a dynamic skill level that adjusts itself based on the players skill level,  by checking wins losses or draws.    8)
Title: Re: zedds "4-in-line" research
Post by: hutch-- on May 02, 2018, 08:57:54 PM
Z,

> I am search for better approaches in determining next move.

Get an old PC somewhere, even if someone chucks one out.
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 02, 2018, 09:16:01 PM
Get an old PC somewhere, even if someone chucks one out.

I have been searching high and low for a good bargain,  but so far no joy   :eusa_boohoo:

But never fear,  in due time I'll be coding my arse off.    :biggrin:   :eusa_dance:

A buddy of mine has a laptop that the HD crapped out on it,  I may look into getting that, a new HD and win 10.   :biggrin
Probably this weekend I can go see the laptop and get specs on it.

later +++
Hopefully I won't have too much trouble locating drivers for it.  But will have to see the laptop first,  as I only was given a brief description.
Title: Re: zedds "4-in-line" research
Post by: Lonewolff on May 03, 2018, 09:43:52 AM
The first version will most likely be console based.

Straight to XBox One! I like your style!  :eusa_clap:
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 03, 2018, 09:58:41 AM
Straight to XBox One! I like your style!  :eusa_clap:

Mainly for algo testing purposes.  After I get the smallest possible accurate board testing algo,   I will go for a Windows version. As it stands right now,  I either have a line by line checking,  or one done with multiple nested loops.  Neither seems very attractive at the moment. But so far,  that's what I got on paper at least.  Either one will work,  and probably be fast enough.  But both of those lack a certain panache, (sp?) and are not very elegant solutions to my dilemma.   :icon_mrgreen:

Edit++
Damn auto correct changing algo to also



Re: my buddies laptop,  it's an Acer... Gonna fire it up shortly to see what the bios tells me.....
Later+++
I opened the bag it was in,  and it's not an Acer it's a Gateway. Go figure.
Model nx570x ,  1 Gig memory,  DVD rw,  1600mhz CPU speed,  Intel T2060 CPU,  system date 07/01/2005  dead cmos battery?  Plug n play os winxp/vista... OK so it doesn't appear to be too old, don't see mfr date anywhere.  Had xp media center originally.  Still has the Genuine Micros++t label,  but highly faded/rubbed off.
Seem very similar to one of my old laptops.

Operating System not found  says POST.    ::)  no kidding,  no hard drive.

Now I've got another friend that says he's got a 60 Gig SSD (he said it was an ssd anyway,  I haven't seen it)   laying around somewhere,  he's got to find it first.  LoL  But if I get that too,  then all I have to do is go to Best Buy or wherever to get Win 10.    :biggrin:


Time to trudge through Gateways driver downloads to search for drivers that are compatible with win10.   :icon_eek:

Edit = copy paste err
Title: Re: zedds "4-in-line" research
Post by: Lonewolff on May 03, 2018, 10:39:03 AM
With a machine that old, Win10 will most likely be fine 'out of the box' without having to dig around with drivers.

You can also download and install Win10 from MS and it will run fine for 30 days before accusing you of being a Pirate.  :bgrin:
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 03, 2018, 10:51:50 AM
With a machine that old, Win10 will most likely be fine 'out of the box' without having to dig around with drivers.
That's good to know.  I'm so used to win xp way of doing things.   :redface:

Well I don't want to put the cart before the horse/oxen/donkey/burro so I'll just sit tight until the hard drive turns up at my friends house.  In the event that it does not,  I will probably look into buying one.  And of course download win10 for 30 day trial,  so I can buy a hard drive if need be.
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 03, 2018, 10:05:37 PM
Quote
r And of course download win10 for 30 day trial,  so I can buy a hard drive if need be.

Slight problem I didn't initially think about,  can't burn iso to disk. So have to get the dvd  :redface:
So it will be soon, just not Real soon,


Classic chicken/egg catch-22
Title: Re: zedds "4-in-line" research
Post by: Lonewolff on May 04, 2018, 09:00:15 AM
Nah, you just make a USB installer, with the Microsoft supplied tool  :t

https://www.microsoft.com/en-us/download/windows-usb-dvd-download-tool

I don't think I have touched a CD in the past 10 years.
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 04, 2018, 09:14:21 AM
Nah, you just make a USB installer, with the Microsoft supplied tool...

Um... All I have is a phone ::) Hence, my dilemma.   ;)
Title: Re: zedds "4-in-line" research
Post by: Lonewolff on May 04, 2018, 09:39:19 AM
Not trying to run desktop windows 10 on your phone are you?  :dazzled:
Title: Re: zedds
Post by: zedd151 on May 04, 2018, 09:45:03 AM
Not trying to run desktop windows 10 on your phone are you?  :dazzled:
 

Only if it were truly possible  :P    :lol:

Nah, I just meant I dont have the means to use the bootable usb tool... Or burn an iso to disk.

chicken/egg scenario.


pss If I could run .exe files on the phone I'd have been coding already.   :biggrin: 

Title: Re: zedds "4-in-line" research
Post by: HSE on May 04, 2018, 11:19:55 AM
pss If I could run .exe files on the phone I'd have been coding already.   :biggrin:

But you can! Just another OS... and another processor... and almost another programming language   :biggrin:

Very funny  :t   
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 04, 2018, 02:14:14 PM

But you can! Just another OS... and another processor... and almost another programming language   :biggrin:


Jeez!  Seems everyone is really getting a kick outta my current situation.

For those people; just think, someday it could happen to you.    :shock: 

 :P    8)
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 04, 2018, 04:06:07 PM
4 in line game.
-------------
game start - empty "board"
-------------

Code: [Select]
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
x x x x x x x

all locations are empty, playable positions are marked with an "x". players piece marked by "1", computer "2".

With the knowledge that this is a "gravity" based game, we know that there is a maximum of 7 available positions at any point in the game, always the lowest available position in any column. available means any position not already filled with either players piece or computers piece.

so every time either computer or player makes a move, the corresponding number is placed in chosen column at lowest available position. an x is placed in the row just above the newly moved piece, to signify new available position in chosen column (unless top already reached and column is full)

After a couple of moves by both sides:
Code: [Select]
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 x 0 0 0
0 x 0 1 x 0 0
x 2 x 1 2 x x
Only the nodes containing "x" in any position need be checked. If there is a zero in any node that node is invalid at this point and need not be checked.

a node is any 4 connecting positions in line, either vertically, horizontally, or diagonally.

Now we need a logical way to represent the positions, as well as a simple way to quickly identify the nodes that need to be checked.

suppose in memory, our board is 56 bytes, corresponding to:
(ascii, since it will be console mode)
Code: [Select]

00 00 00 00 00 00 00 ff ;top row - x here means column is full
-----------------------
30 30 30 30 30 30 30 ff
30 30 30 30 30 30 30 ff
30 30 30 30 30 30 30 ff
30 30 30 78 30 30 30 ff
30 78 30 31 78 30 30 ff
78 32 78 31 32 78 78 ff
where the positions filled with ff (-1) are invalid positions, used for alignment only and not displayed.

--- more to follow ---

Title: Re: zedds "4-in-line" research
Post by: felipe on May 05, 2018, 01:56:17 AM
Ah, i see what you mean now by four in line. I actually have played this game in a DOS version named four. Was very funny and challenging  :biggrin:. I think checking the diagonal nodes will be the hard part.  :idea:
Title: Re: zedds "4-in-line" research
Post by: zedd151 on May 05, 2018, 04:38:57 AM
Ah, i see what you mean now by four in line.

So as not to be confused with Hasbro's Connect Four ®™ .  They are very protective of their trademarked product and its name.
Quote
I think checking the diagonal nodes will be the hard part.  :idea:
No not really, but the code will surely have a lot of nested "if" statements, until I figure out a better way to do it,
Title: Skeleton of a program
Post by: zedd151 on May 06, 2018, 01:31:43 AM
Here is the skeleton I so blatantly stole from my 4x4 console version - reworked a bit to be more useful here.

Code: [Select]
removed buggy code  :P

I will keep adding to it, or modifying it until the game is completed.
Doing this kind of stuff is tedious on a phone.  :badgrin:  I should have computer up and running before this games completion.


Title: UPDATE!!!!!
Post by: zedd151 on May 06, 2018, 04:28:26 AM
Coming soon in glorious 64 bit, high definition, living color, and in 4D....

zedds game.    :biggrin:
Title: Four in a Row.
Post by: zedd151 on May 07, 2018, 10:33:36 AM
Coming soon in glorious 64 bit, high definition, living color, and in 4D....

Well, not exactly...   :greensml:
Windows version of Four in a Row. (I like the name better than 4 in line)

Code: [Select]
        include \masm32\include\masm32rt.inc

        WinMain     proto
        LoadPix     proto :dword, :dword
        randb       proto :dword       
        painting    proto :dword

    .data
        hInstance   dd 0
        hWnd        dd 0

        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
        column      dd 0
        board       db 35 dup (0)
        zz          db 7 dup (-1)

        wc              WNDCLASSEX  <>
        bord           db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0

        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 00000000h
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc

        mov Wwd, 448
        mov Wht, 384
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b

        invoke CreateWindowEx, 0, addr szClassName,
        addr szDisplayName, 90080800h, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:

        invoke GetMessage, addr msg, 0, 0, 0
        cmp eax, 0
        je ExitLoop
        invoke DispatchMessage, addr msg
        jmp StartLoop

    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
        .if uMsg == WM_CREATE
   
            invoke LoadImage, 0, addr bord, IMAGE_BITMAP, 0, 0, 50h
            mov hBoard, eax
            invoke LoadImage, 0, addr red, IMAGE_BITMAP, 0, 0, 50h
            mov hRed, eax
            invoke LoadImage, 0, addr blue, IMAGE_BITMAP, 0, 0, 50h
            mov hBlue, eax
   
        .elseif uMsg == WM_LBUTTONDOWN
       
            push eax
            mov eax, lParam
            and eax, 0FFFFh
            shr eax,6
            inc eax
            mov column, eax
            pop eax
   
        .elseif uMsg == WM_LBUTTONUP
            push esi
            lea esi, board
           
            .if column == 1
              .if byte ptr [esi+35] == -1
              jmp is1
              .if byte ptr [esi+28] == -1
              jmp is1
              .if byte ptr [esi+21] == -1
              jmp is1
              .if byte ptr [esi+14] == -1
              jmp is1
              .if byte ptr [esi+7] == -1
              jmp is1
              .if byte ptr [esi] == -1
              jmp is1
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over1
            is1:
            over1:

            inc esi
            .if column == 2
              .if byte ptr [esi+35] == -1
              jmp is2
              .if byte ptr [esi+28] == -1
              jmp is2
              .if byte ptr [esi+21] == -1
              jmp is2
              .if byte ptr [esi+14] == -1
              jmp is2
              .if byte ptr [esi+7] == -1
              jmp is2
              .if byte ptr [esi] == -1
              jmp is2
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over2
            is2:
            over2:

            inc esi
            .if column == 3
              .if byte ptr [esi+35] == -1
              jmp is3
              .if byte ptr [esi+28] == -1
              jmp is3
              .if byte ptr [esi+21] == -1
              jmp is3
              .if byte ptr [esi+14] == -1
              jmp is3
              .if byte ptr [esi+7] == -1
              jmp is3
              .if byte ptr [esi] == -1
              jmp is3
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over3
            is3:
            over3:

            inc esi
            .if column == 4
              .if byte ptr [esi+35] == -1
              jmp is4
              .if byte ptr [esi+28] == -1
              jmp is4
              .if byte ptr [esi+21] == -1
              jmp is4
              .if byte ptr [esi+14] == -1
              jmp is4
              .if byte ptr [esi+7] == -1
              jmp is4
              .if byte ptr [esi] == -1
              jmp is4
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over4
            is4:
            over4:

            inc esi
            .if column == 5
              .if byte ptr [esi+35] == -1
              jmp is5
              .if byte ptr [esi+28] == -1
              jmp is5
              .if byte ptr [esi+21] == -1
              jmp is5
              .if byte ptr [esi+14] == -1
              jmp is5
              .if byte ptr [esi+7] == -1
              jmp is5
              .if byte ptr [esi] == -1
              jmp is5
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over5
            is5:
            over5:

            inc esi
            .if column == 6
              .if byte ptr [esi+35] == -1
              jmp is6
              .if byte ptr [esi+28] == -1
              jmp is6
              .if byte ptr [esi+21] == -1
              jmp is6
              .if byte ptr [esi+14] == -1
              jmp is6
              .if byte ptr [esi+7] == -1
              jmp is6
              .if byte ptr [esi] == -1
              jmp is6
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over6
            is6:
            over6:

            inc esi
            .if column == 7
              .if byte ptr [esi+35] == -1
              jmp is7
              .if byte ptr [esi+28] == -1
              jmp is7
              .if byte ptr [esi+21] == -1
              jmp is7
              .if byte ptr [esi+14] == -1
              jmp is7
              .if byte ptr [esi+7] == -1
              jmp is7
              .if byte ptr [esi] == -1
              jmp is7
              .endif
              .endif
              .endif
              .endif
              .endif
              .endif
            .endif
            jmp over7
            is7:
            over7:


   
        .elseif uMsg == WM_PAINT
            invoke painting, hWnd

        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        inc eax
        ret
    randb endp

    painting proc hWin:dword
    local tX:dword, tY:dword, hDC:dword, hMemDC:dword, numb:dword
        push esi
        push edi
        push ebx
        invoke GetWindowDC, hWin
        mov hDC, eax
        invoke CreateCompatibleDC, NULL
        mov hMemDC, eax

        invoke SelectObject, hMemDC, hBoard
        invoke BitBlt, hDC, 0, 0, 448, 384, hMemDC, 0, 0, SRCCOPY

        ;invoke SelectObject, hMemDC, hRed
        ;invoke BitBlt, hDC, 0, 0, 64, 64, hMemDC, 0, 0, SRCCOPY

        ;invoke SelectObject, hMemDC, hBlue
        ;invoke BitBlt, hDC, 0, 0, 64, 64, hMemDC, 0, 0, SRCCOPY

        invoke DeleteDC, hMemDC
        invoke DeleteDC, hDC
        pop ebx
        pop edi
        pop esi
        ret
    painting endp

    end start

It's not much, but it's what I've coded thus far in my spare time. Nowhere near completed yet.

later--> Added a little code to check which column the mouse was clicked in.
Title: Re: zedds "Four in a Row" research
Post by: zedd151 on May 07, 2018, 12:57:35 PM
A different approach...

Code: [Select]
        include \masm32\include\masm32rt.inc

        WinMain     proto
        LoadPix     proto :dword, :dword
        randb       proto :dword       
        DisplayBmp  proto :dword, :dword, :dword, :dword, :dword
    .data
        hInstance   dd 0
        hWnd        dd 0
        hDC         dd 0
        hMemDC      dd 0
        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
        column      dd 0
        row         dd 0
        board       db 35 dup (0)
        zz          db 7 dup (-1)
        xx          dd 0
        yy          dd 0

        wc              WNDCLASSEX  <>
        bord            db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0
        stWin           db "STATIC",0
        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 00000000h
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc

        mov Wwd, 448
        mov Wht, 384
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b

        invoke CreateWindowEx, 0, addr szClassName,
        addr szDisplayName, 90080800h, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:

        invoke GetMessage, addr msg, 0, 0, 0
        cmp eax, 0
        je ExitLoop
        invoke DispatchMessage, addr msg
        jmp StartLoop

    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
        .if uMsg == WM_CREATE
            invoke DisplayBmp, hWin, 100, 0, 0, 20
   
        .elseif uMsg == WM_LBUTTONDOWN
       
            mov eax, lParam
            and eax, 0FFFFh
            shr eax,6
            inc eax
            mov column, eax
   
            lea eax, board
           
            .if column == 1
              mov yy, 0
              .if byte ptr [eax+35d] == -1
              mov row, 1
              mov xx, 320
              jmp is1
              .elseif byte ptr [eax+28d] == -1
              mov row, 2
              jmp is1
              .elseif byte ptr [eax+21d] == -1
              mov row, 3
              jmp is1
              .elseif byte ptr [eax+14d] == -1
              mov row, 4
              jmp is1
              .elseif byte ptr [eax+7d] == -1
              mov row, 5
              jmp is1
              .elseif byte ptr [eax] == -1
              mov row, 6
              jmp is1
              .endif
            .endif
            jmp over1
            is1:
            invoke DisplayBmp, hWin, 120, yy, xx, 30
            over1:

   
        .elseif uMsg == WM_PAINT

        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        inc eax
        ret
    randb endp

    DisplayBmp proc hParent:DWORD,bmpID:DWORD,x:DWORD,y:DWORD,ID:DWORD
        LOCAL hModule:DWORD
        LOCAL hBmp   :DWORD
        LOCAL hImage :DWORD
        invoke GetModuleHandle,NULL
        mov hModule, eax
        invoke CreateWindowEx,WS_EX_LEFT,
                ADDR stWin,NULL,
                WS_CHILD or WS_VISIBLE or SS_BITMAP,
                x,y,0,0,hParent,ID,
                hModule,NULL
        mov hImage, eax
        invoke LoadBitmap,hModule,bmpID
        mov hBmp, eax
        invoke SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp
        mov eax, hImage
        ret
    DisplayBmp endp

    end start

Using static control for "pieces". A little quirky just now, in that the row must be clicked twice for the static image to appear....
only row 1 works for now...


Later --->>>

I found out what the problem is.   :icon_redface:
And I'm working on fixing it.
Title: Re: Four in a Row R&D
Post by: zedd151 on May 07, 2018, 04:56:41 PM
Now, something I can work with...

       
Code: [Select]
        include \masm32\include\masm32rt.inc

        WinMain     proto
        LoadPix     proto :dword, :dword
        randb       proto :dword       
        DisplayBmp  proto :dword, :dword, :dword, :dword, :dword
    .data
        count       dd 0
        hInstance   dd 0
        hWnd        dd 0
        hDC         dd 0
        hMemDC      dd 0
        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
        column      dd 0
        row         dd 0
        topx        db 7 dup (0)
        board       db 35 dup (0)
        zz          db 7 dup (-1)
        xx          dd 0
        yy          dd 0
        done        dd 0

        wc              WNDCLASSEX  <>
        bord            db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0
        stWin           db "STATIC",0
        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
       
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 0000ffffh
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc

        mov Wwd, 469
        mov Wht, 428
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b

                             
        invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, addr szClassName,
        addr szDisplayName, WS_OVERLAPPEDWINDOW, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    LOCAL Ps     :PAINTSTRUCT
        .if uMsg == WM_CREATE
                   
   
        .elseif uMsg == WM_LBUTTONDOWN
       
            mov eax, lParam
            and eax, 0FFFFh
            shr eax,6
            inc eax
            mov column, eax
   
            lea eax, board
            dec eax
            add eax, column

           
            .if column == 1
              mov yy, 0
            .elseif column == 2
              mov yy, 64
            .elseif column == 3
              mov yy, 128
            .elseif column == 4
              mov yy, 192
            .elseif column == 5
              mov yy, 256
            .elseif column == 6
              mov yy, 320
            .elseif column == 7
              mov yy, 384
            .endif
           
              call movit




   
        .elseif uMsg == WM_PAINT
       
       
;-------------------- create lines in the game board ------------------     
   
        jmp ttt
        cords dd 0,64,128,192,256,320,384,448   ; ------- coordinates
        ttt:


        push esi
        push edi
        push ebx
       
        lea esi, cords
        mov edi, 448
        mov ebx, 448
       
        @@:
        invoke line, hWin, 0, 0, [esi], edi, [esi]
        add esi, 4
        cmp [esi], ebx
        jl @b
       
        lea esi, cords
        mov edi, 384
        mov ebx, 512
       
        @@:
        invoke line, hWin, 0,  [esi], 0, [esi], edi
        add esi, 4
        cmp [esi], ebx
        jl @b

        pop ebx
        pop edi
        pop esi

       
        invoke BeginPaint,hWin,ADDR Ps
        mov hDC, eax
        invoke EndPaint,hWin,ADDR Ps
        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    movit proc
   
        .if byte ptr [eax+35] == -1
            mov row, 1
            mov xx, 320
            mov byte ptr [eax+35], 1
            mov byte ptr [eax+28], -1
            jmp is1
           
        .elseif byte ptr [eax+28] == -1
            mov row, 2
            mov xx, 256
            mov byte ptr [eax+28], 1
            mov byte ptr [eax+21], -1
            jmp is1
           
        .elseif byte ptr [eax+21] == -1
            mov row, 3
            mov xx, 192
            mov byte ptr [eax+21], 1
            mov byte ptr [eax+14], -1
            jmp is1
           
        .elseif byte ptr [eax+14] == -1
            mov row, 4
            mov xx, 128
            mov byte ptr [eax+14], 1
            mov byte ptr [eax+7], -1
            jmp is1
           
        .elseif byte ptr [eax+7] == -1
            mov row, 5
            mov xx, 64
            mov byte ptr [eax+7], 1
            mov byte ptr [eax], -1
            jmp is1
           
        .elseif byte ptr [eax] == -1
            mov row, 6
            mov xx, 0
            mov byte ptr [eax], 1
            mov byte ptr [eax-7], -1
            jmp is1
            is1:
            add xx, 3
            add yy, 3
            invoke DisplayBmp, hWnd, 120, yy, xx, 30
        .endif
        ret
    movit endp

    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        inc eax
        ret
    randb endp

    DisplayBmp proc hParent:DWORD,bmpID:DWORD,x:DWORD,y:DWORD,ID:DWORD
        LOCAL hModule:DWORD
        LOCAL hBmp   :DWORD
        LOCAL hImage :DWORD
        invoke GetModuleHandle,NULL
        mov hModule, eax
        invoke CreateWindowEx,WS_EX_LEFT,
                ADDR stWin,NULL,
                WS_CHILD or WS_VISIBLE or SS_BITMAP,
                x,y,0,0,hParent,ID,
                hModule,NULL
        mov hImage, eax
        invoke LoadBitmap,hModule,bmpID
        mov hBmp, eax
        invoke SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp
        mov eax, hImage
        ret
    DisplayBmp endp

    end start

All columns are working as they should. Click on a column, and your piece is placed at the bottom-most vacant location in that column.   :biggrin:

Now to start working on the AI portion of the game.   :icon_eek:
After that is pretty much taken care of, I will then work on the "dynamic skill level". For more skilled players, will be more challenging. for less skilled players, it will be easier. I want to try to keep the computer versus human win ratio to a reasonable level, so it will be fun as well as challenging to play. Should be that the human player wins between 45 and 55 % of the games. But I may adjust those numbers during development of the game.

>> Later
Found a flaw in the design. I need to check whether the column is full....
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 08, 2018, 12:30:09 AM
some more code tweaks...

Code: [Select]
        include \masm32\include\masm32rt.inc

        WinMain     proto
        LoadPix     proto :dword, :dword
        randb       proto :dword       
        DisplayBmp  proto :dword, :dword, :dword, :dword, :dword
    .data
        count       dd 0
        hInstance   dd 0
        hWnd        dd 0
        hDC         dd 0
        hMemDC      dd 0
        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
        column      dd 0
        row         dd 0
        topx        db 7 dup (0)
        board       db 35 dup (0)
        zz          db 7 dup (-1)
        xx          dd 0
        yy          dd 0
        done        dd 0

        wc              WNDCLASSEX  <>
        bord            db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0
        stWin           db "STATIC",0
        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
       
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 0000ffffh
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc

        mov Wwd, 455
        mov Wht, 414
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b

                             
        invoke CreateWindowEx, WS_EX_LEFT, addr szClassName,
        addr szDisplayName, WS_SYSMENU, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    LOCAL Ps     :PAINTSTRUCT
        .if uMsg == WM_CREATE
                   
   
        .elseif uMsg == WM_LBUTTONDOWN

; ------- >>> streamlined the code below
       
            mov eax, lParam
            and eax, 0FFFFh
            shr eax,6
            mov column, eax
   
            lea eax, board
            add eax, column

            mov ecx, column
            shl ecx, 6  ; round off for bmp position
            mov yy, ecx

            call movit

; ------- >>> streamlined the code above


   
        .elseif uMsg == WM_PAINT
       
       
;-------------------- create lines in the game board ------------------     
   
        jmp ttt
        cords dd 0,64,128,192,256,320,384,448   ; ------- coordinates
        ttt:


        push esi
        push edi
        push ebx
       
        lea esi, cords
        mov edi, 448
        mov ebx, 448
       
        @@:
        invoke line, hWin, 0, 0, [esi], edi, [esi]
        add esi, 4
        cmp [esi], ebx
        jl @b
       
        lea esi, cords
        mov edi, 384
        mov ebx, 512
       
        @@:
        invoke line, hWin, 0,  [esi], 0, [esi], edi
        add esi, 4
        cmp [esi], ebx
        jl @b

        pop ebx
        pop edi
        pop esi

       
        invoke BeginPaint,hWin,ADDR Ps
        mov hDC, eax
        invoke EndPaint,hWin,ADDR Ps
        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    movit proc
        .if byte ptr [eax-7] == -1
        jmp ww
        .endif
        .if byte ptr [eax+35] == -1
            mov row, 1
            mov xx, 320
            mov byte ptr [eax+35], 1
            mov byte ptr [eax+28], -1
            jmp is1
           
        .elseif byte ptr [eax+28] == -1
            mov row, 2
            mov xx, 256
            mov byte ptr [eax+28], 1
            mov byte ptr [eax+21], -1
            jmp is1
           
        .elseif byte ptr [eax+21] == -1
            mov row, 3
            mov xx, 192
            mov byte ptr [eax+21], 1
            mov byte ptr [eax+14], -1
            jmp is1
           
        .elseif byte ptr [eax+14] == -1
            mov row, 4
            mov xx, 128
            mov byte ptr [eax+14], 1
            mov byte ptr [eax+7], -1
            jmp is1
           
        .elseif byte ptr [eax+7] == -1
            mov row, 5
            mov xx, 64
            mov byte ptr [eax+7], 1
            mov byte ptr [eax], -1
            jmp is1
           
        .elseif byte ptr [eax] == -1
            mov row, 6
            mov xx, 0
            mov byte ptr [eax], 1
            mov byte ptr [eax-7], -1
            is1:
        .endif
       
            add xx, 3 ; adj for bmp size
            add yy, 3 ; adj for bmp size
           
            invoke DisplayBmp, hWnd, 120, yy, xx, 30
        ww:
        ret
    movit endp

    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        inc eax
        ret
    randb endp

    DisplayBmp proc hParent:DWORD,bmpID:DWORD,x:DWORD,y:DWORD,ID:DWORD
        LOCAL hModule:DWORD
        LOCAL hBmp   :DWORD
        LOCAL hImage :DWORD
        invoke GetModuleHandle,NULL
        mov hModule, eax
        invoke CreateWindowEx,WS_EX_LEFT,
                ADDR stWin,NULL,
                WS_CHILD or WS_VISIBLE or SS_BITMAP,
                x,y,0,0,hParent,ID,
                hModule,NULL
        mov hImage, eax
        invoke LoadBitmap,hModule,bmpID
        mov hBmp, eax
        invoke SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp
        mov eax, hImage
        ret
    DisplayBmp endp

    end start

Title: Re: Four in a Row - R&D
Post by: zedd151 on May 08, 2018, 06:43:15 AM
Changed the bmps for the game, and changed the data arrangement for the game board.

Title: Re: Four in a Row - R&D
Post by: zedd151 on May 08, 2018, 07:30:56 PM
Further code reduction, and removing redundancies. Still a one-player game, lol.

Code: [Select]


        include \masm32\include\masm32rt.inc

        WinMain     proto
        randb       proto :dword       
        DisplayBmp  proto :dword, :dword, :dword, :dword, :dword
       
    .data
   
        topx        db 8 dup (0)
        board       db 40 dup (0)
        zz          db 8 dup (-1)

        count       dd 0
        hInstance   dd 0
        hWnd        dd 0
        hDC         dd 0
       
        hMemDC      dd 0
        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
       
        column      dd 0
        xx          dd 0
        yy          dd 0
        done        dd 0
       
        wc              WNDCLASSEX  <>
        bord            db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0
        stWin           db "STATIC",0
        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
       
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 0000ffffh
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc
       
        push ebx
        mov Wwd, 455
        mov Wht, 414
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b
        pop ebx
                             
        invoke CreateWindowEx, WS_EX_LEFT, addr szClassName,
        addr szDisplayName, WS_SYSMENU, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    LOCAL Ps     :PAINTSTRUCT
        .if uMsg == WM_CREATE
                   
   
        .elseif uMsg == WM_LBUTTONDOWN
       
; ---------------- further codesize optimizations below ---------------

            mov eax, lParam
            and eax, 0FFFFh
            shr eax,6 ; ------- column number (0-6)
            mov column, eax
            shl eax, 6 ; ------- y coord of row
            mov yy, eax
            lea eax, board
            add eax, column ; -------- location of column on board
            cmp byte ptr [eax-8], -1
            jz ww
            mov edx, 320
            hhh:
            mov ecx, edx           
            mov xx, ecx
            sar ecx, 3
        .if byte ptr [eax+ecx] == -1     ; if space is playable
            mov byte ptr [eax+ecx], 1    ; mark space occupied
            sub ecx, 8
            mov byte ptr [eax+ecx], -1   ; same column, mark space in row above playable
            add xx, 3 ; adj for bmp size
            add yy, 3 ; adj for bmp size
            invoke DisplayBmp, hWnd, 120, yy, xx, 30
            jmp ww
        .endif
            sub edx, 64
            jmp hhh
       
        ww:
; ---------------------------------------------------------------------


   
        .elseif uMsg == WM_PAINT
       
        jmp ttt
        cords dd 0,64,128,192,256,320,384,448   ; ------- coordinates
        ttt:
        push esi
        push edi
        push ebx
       
        lea esi, cords
        mov edi, 448
        mov ebx, 448
        @@:
        invoke line, hWin, 0, 0, [esi], edi, [esi]
        add esi, 4
        cmp [esi], ebx
        jl @b
        lea esi, cords
        mov edi, 384
        mov ebx, 512
        @@:
        invoke line, hWin, 0,  [esi], 0, [esi], edi
        add esi, 4
        cmp [esi], ebx
        jl @b

        pop ebx
        pop edi
        pop esi
       
        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        inc eax
        ret
    randb endp

    DisplayBmp proc hParent:DWORD,bmpID:DWORD,x:DWORD,y:DWORD,ID:DWORD
        LOCAL hModule:DWORD
        LOCAL hBmp   :DWORD
        LOCAL hImage :DWORD
        invoke GetModuleHandle,NULL
        mov hModule, eax
        invoke CreateWindowEx,WS_EX_LEFT,
                ADDR stWin,NULL,
                WS_CHILD or WS_VISIBLE or SS_BITMAP,
                x,y,0,0,hParent,ID,
                hModule,NULL
        mov hImage, eax
        invoke LoadBitmap,hModule,bmpID
        mov hBmp, eax
        invoke SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp
        mov eax, hImage
        ret
    DisplayBmp endp

    end start


Will put the "human player" code into a procedure before moving on to make the "computer player".
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 08, 2018, 08:07:45 PM
Okay, now I am finished with shortening the code that I have so far, and putting the "human player" code into its' own proc. Here it is in the attachment.
It is still a one-player game, so don't expect too much from it.
Now that is taken care of, I will start coding the "computer player". That should make it much more interesting, both for the player as well as the intrepid coder.   :biggrin:














Title: Re: Four in a Row - R&D
Post by: caballero on May 09, 2018, 04:06:55 AM
Good starting point :t
Title: Re: Four in a Row - R&D
Post by: daydreamer on May 09, 2018, 05:19:41 AM
good start
when researching unicode, I found out there is also non-language things that can be useful if you make simple:
 games,geometric shape s
Chess, Checkers/Draughts
Domino Tiles
Japanese Chess
Mahjong Tiles
Playing Cards
Card suits
Miscellaneous Symbols and Arrows
so with newer OS you maybe have unicode support when running console it would maybe be possible with a console card game,chess etc


Title: Re: Four in a Row - R&D
Post by: zedd151 on May 09, 2018, 06:33:32 AM

Good starting point :t



good start
when researching unicode, I found out there is also non-language things that can be useful if you make simple....



Thanks to both of you. This idea has been rattling around in my head for some time.  Now I have the opportunity to see it through to fruition.       :biggrin:
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 09, 2018, 09:25:12 AM
Now THIS is not very elegant. Sure it gets the job done, but covfefe...

Code: [Select]

    .if byte ptr [esi] == -1
      .if byte ptr [esi+1] == 1
        .if byte ptr [esi+2] == 1
          .if byte ptr [esi+3] != 2
            .if byte ptr [esi+3] != 0
           
              mov byte ptr [esi], 2
              mov byte ptr [esi-8], -1
              jmp @f

            .endif
          .endif
        .endif
      .endif
    .endif


... will be prone to buggy code, especially when a few dozen are needed.    :icon_eek:
But in assembly, there's always another way.

I was just trying something, and got lost along the way.

Instead of the above code, how about using seperate byte sized  variables for the played
pieces? The code then could look like this....

Code: [Select]


    .if s40==-1 && s41==1 && s42==1 && 43!=2 || s40==-1 && s41 ==1 && s42==1 && s43!=0
        mov s40, 2
        mov s32, -1
    .endif

Looks a bit tidier, I think. But I don't know what the assembled cmps and jmps will look like.
Title: Re: Four in a Row - R&D
Post by: jj2007 on May 09, 2018, 05:48:09 PM
Code: [Select]
    mov al, [esi+3]
    .if byte ptr [esi] == -1 && byte ptr [esi+1] == 1 && byte ptr [esi+2] == 1 && al != 2 && al
              mov byte ptr [esi], 2
              mov byte ptr [esi-8], -1
              jmp @f
    .endif

There is a more efficient version, though. Having an unconditional jmp inside a bunch of conditions always means that you could save two bytes ;-)
Title: Re: Four in a Row - R&D
Post by: LordAdef on May 10, 2018, 12:50:42 PM
how about a bitwise operation with mask instead of all those if?
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 10, 2018, 01:45:20 PM
how about a bitwise operation with mask instead of all those if?

I had thought about doing something like that, but as I've never done it - I'm not sure exactly how to implement it. But since the game is still in R&D, I'll experiment.  Thanks for the tip.   :icon14:
Title: Re: Four in a Row - R&D
Post by: LordAdef on May 10, 2018, 01:52:35 PM
one more thing, and this is actually a question:


.if byte ptr [esi] == -1


Does this really work?
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 10, 2018, 03:56:44 PM
Does this really work?

Yes.
Title: Re: Four in a Row - R&D
Post by: daydreamer on May 10, 2018, 05:28:52 PM
Zedd,backtrack in this thread to your earlier posted a great data structure for console version
There is ascii char data,but also strings and nibbles
And a nice structure made for x8 scaling indirect register

Title: Re: Four in a Row - R&D
Post by: aw27 on May 10, 2018, 06:50:09 PM
I found this http://www.cplusplus.com/forum/general/120742/. I did not convert it to MASM because I have no time right now, but is straightforward.
However, I fixed it because it had a few bugs, built and tested. Looks cool right now. I include also the .exe

Title: Re: Four in a Row - R&D
Post by: zedd151 on May 11, 2018, 01:03:40 AM
... Looks cool right now. I include also the .exe

Thanks aw27, but as I don't know c++ it won't help me too much. The only thing I can do with it is look at the exe under the hood.


@daydreamer

Thanks, I might just do that and fully develop the console version.
Title: Re: Four in a Row - R&D
Post by: aw27 on May 11, 2018, 02:02:54 AM
All right, look at it as pseudo code then, a nod is as good as a wink (to a blind horse, according to the old say)  :biggrin:
Title: Four in a Row - Two Player Mode
Post by: zedd151 on May 13, 2018, 04:35:54 AM
Code: [Select]

        include \masm32\include\masm32rt.inc

        WinMain     proto
        WndProc     proto :dword, :dword, :dword, :dword
        human       proto :dword, :dword, :dword
        computer    proto :dword, :dword, :dword
        checkdone   proto :dword
        randb       proto :dword       
        DisplayBmp  proto :dword, :dword, :dword, :dword, :dword
       
    .data
   
        topx        db 8 dup (0)
        board       db 40 dup (0)
        zz          db 8 dup (-1)

        count       dd 0
        hInstance   dd 0
        hWnd        dd 0
        hDC         dd 0
       
        hMemDC      dd 0
        hBoard      dd 0
        hRed        dd 0
        hBlue       dd 0
       
        column      dd 0
        xx          dd 0
        yy          dd 0
        done        dd 0
        turn        dd 1
       
        wc              WNDCLASSEX  <>
        bord            db "board.bmp", 0
        blue            db "blue.bmp", 0
        red             db "red.bmp", 0
        stWin           db "STATIC",0
        szDisplayName   db "Four in a Row", 0
        szClassName     db "Game", 0

    .code

    start:
        invoke WinMain
        invoke ExitProcess, hInstance

    WinMain proc
    local msg:MSG, Wwd:dword, Wht:dword, Wtx:dword, Wty:dword

        push ebx
       
        invoke GetModuleHandle, NULL
        mov hInstance, eax
        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset WndProc
        m2m wc.hInstance, hInstance
        invoke CreateSolidBrush, 0000ffffh
        mov wc.hbrBackground, eax
        mov wc.lpszClassName, offset szClassName
        invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax
        invoke RegisterClassEx, addr wc
       
        push ebx
        mov Wwd, 455
        mov Wht, 414
        lea edi, Wtx
        mov edx, Wwd
        mov ebx, 0
        @@:
        push edx
        invoke GetSystemMetrics, ebx
        pop edx
        shr eax, 1
        shr edx, 1
        sub eax, edx
        mov [edi], eax
        lea edi, Wty
        mov edx, Wht
        inc ebx
        cmp ebx, 2
        jnz @b
        pop ebx
                             
        invoke CreateWindowEx, WS_EX_LEFT, addr szClassName,
        addr szDisplayName, WS_SYSMENU, Wtx, Wty, Wwd, Wht, 0, 0, hInstance, 0
        mov hWnd, eax
        invoke ShowWindow, hWnd, SW_SHOWNORMAL
        invoke UpdateWindow, hWnd

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
        pop ebx
        ret
    WinMain endp

    WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
    LOCAL Ps     :PAINTSTRUCT
        .if uMsg == WM_CREATE
                   
   
        .elseif uMsg == WM_LBUTTONDOWN
       
            .if turn==1
           
                invoke human, hWnd, lParam, addr board
               
                ret
               
            .elseif turn==2
           
                invoke computer, hWnd, lParam, addr board
               
            .endif
       
        .elseif uMsg == WM_PAINT
       
        jmp ttt
        cords dd 0,64,128,192,256,320,384,448   ; ------- coordinates
        ttt:
        push esi
        push edi
        push ebx
       
        lea esi, cords
        mov edi, 448
        mov ebx, 448
        @@:
        invoke line, hWin, 0, 0, [esi], edi, [esi]
        add esi, 4
        cmp [esi], ebx
        jl @b
        lea esi, cords
        mov edi, 384
        mov ebx, 512
        @@:
        invoke line, hWin, 0,  [esi], 0, [esi], edi
        add esi, 4
        cmp [esi], ebx
        jl @b

        pop ebx
        pop edi
        pop esi
       
        .elseif uMsg == WM_CLOSE
            invoke PostQuitMessage, NULL
            return 0

        .endif
        invoke DefWindowProc, hWin, uMsg, wParam, lParam
        ret
    WndProc endp

    human proc, hwin:dword, lparm:dword, bdoffs:dword
        local cnum:dword, xxx:dword, yyy:dword
       
        mov eax, lparm
        and eax, 0FFFFh
        shr eax,6 ; ------- column number (0-6)
        mov cnum, eax
        shl eax, 6 ; ------- y coord of row
        mov yyy, eax
        mov eax, bdoffs
        add eax, cnum ; -------- location of column on board
        cmp byte ptr [eax-8], -1
        jz ww
        mov edx, 320
    hhh:
        mov ecx, edx           
        mov xxx, ecx
        sar ecx, 3
    .if byte ptr [eax+ecx] == -1     ; if space is playable
        mov byte ptr [eax+ecx], 1    ; mark space occupied
        sub ecx, 8
        mov byte ptr [eax+ecx], -1   ; same column, mark space in row above playable
        add xxx, 3 ; adj for bmp size
        add yyy, 3 ; adj for bmp size
        invoke DisplayBmp, hwin, 120, yyy, xxx, 30
        mov turn, 2
        jmp ww
    .endif
        sub edx, 64
        jmp hhh
   
    ww:
        ret
    human endp

    checkdone proc bdoffs:dword ;---->> not implemented yet
        ret
    checkdone endp

    ;--->> At this point, the computer player is only a second human player
   
    computer proc hwin:dword, lparm:dword, bdoffs:dword
    local cnum:dword, xxx:dword, yyy:dword
       
        mov eax, lparm
        and eax, 0FFFFh
        shr eax,6 ; ------- column number (0-6)
        mov cnum, eax
        shl eax, 6 ; ------- y coord of row
        mov yyy, eax
        mov eax, bdoffs
        add eax, cnum ; -------- location of column on board
        cmp byte ptr [eax-8], -1
        jz ww
        mov edx, 320
    hhh:
        mov ecx, edx           
        mov xxx, ecx
        sar ecx, 3
    .if byte ptr [eax+ecx] == -1     ; if space is playable
        mov byte ptr [eax+ecx], 1    ; mark space occupied
        sub ecx, 8
        mov byte ptr [eax+ecx], -1   ; same column, mark space in row above playable
        add xxx, 3 ; adj for bmp size
        add yyy, 3 ; adj for bmp size
        invoke DisplayBmp, hwin, 110, yyy, xxx, 20
        mov turn, 1
        jmp ww
    .endif
        sub edx, 64
        jmp hhh
   
    ww:
        ret
    computer endp

   
    randb proc base:dword
    local random_seed:dword
        invoke GetTickCount
        add eax, random_seed
        xor edx, edx
        mov ecx, 127773
        div ecx
        mov ecx, eax
        mov eax, 432836
        mul edx
        sub ecx, eax
        xor edx, edx
        mov eax, ecx
        mov random_seed, ecx
        div base
        mov eax, edx
        ;inc eax
        ret
    randb endp

    DisplayBmp proc hParent:DWORD,bmpID:DWORD,x:DWORD,y:DWORD,ID:DWORD
        LOCAL hModule:DWORD
        LOCAL hBmp   :DWORD
        LOCAL hImage :DWORD
        invoke GetModuleHandle,NULL
        mov hModule, eax
        invoke CreateWindowEx,WS_EX_LEFT,
                ADDR stWin,NULL,
                WS_CHILD or WS_VISIBLE or SS_BITMAP,
                x,y,0,0,hParent,ID,
                hModule,NULL
        mov hImage, eax
        invoke LoadBitmap,hModule,bmpID
        mov hBmp, eax
        invoke SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmp
        mov eax, hImage
        ret
    DisplayBmp endp

    end start

I know it's not much, but I AM working on the AI for the computer 'player'. Might even be a rewrite of a few things....

still a quirk with this one  ;)

code above, exe in attachment - use same resources, etc.
Title: Artificial Intelligence?
Post by: zedd151 on May 13, 2018, 02:50:01 PM
Or simply artificial randomness.    :biggrin:

Attached is a version where the computer randomly places a piece immediately after the players move.
No checking of win/lose/draw condition yet.

Working on a new, improved 4 in a row...
Title: Re: Four in a Row - R&D
Post by: zedd151 on May 14, 2018, 02:01:51 AM
Improved the code for the random computer opponent version.

Code: [Select]

.

edit==remove buggy attachment   and code :icon_eek:

found a bug just after posted, now the computer is able to make more moves than the player.   :(
.... more later ...
Title: Re: Four in a Row - R&D
Post by: felipe on May 14, 2018, 05:06:50 AM
found a bug just after posted, now the computer is able to make more moves than the player.   :(

Hey don't get discouraged, that sounds like authentic AI... :biggrin: