├── .vs
├── ProjectSettings.json
└── slnx.sqlite
├── screenshots
├── ingame.jpg
├── youdied.png
└── startscreen.png
├── main.asm
├── main.asm
│ ├── main.asm.vcxproj.filters
│ ├── main.asm.vcxproj
│ └── main.asm
└── main.asm.sln
├── LICENSE
├── .gitattributes
├── README.md
└── .gitignore
/.vs/ProjectSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentProjectSetting": null
3 | }
--------------------------------------------------------------------------------
/.vs/slnx.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/.vs/slnx.sqlite
--------------------------------------------------------------------------------
/screenshots/ingame.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/ingame.jpg
--------------------------------------------------------------------------------
/screenshots/youdied.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/youdied.png
--------------------------------------------------------------------------------
/screenshots/startscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meixinchoy/Snake-Game-Assembly-Language/HEAD/screenshots/startscreen.png
--------------------------------------------------------------------------------
/main.asm/main.asm/main.asm.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 meixinchoy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/main.asm/main.asm.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.1209
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "main.asm", "main.asm\main.asm.vcxproj", "{EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x64.ActiveCfg = Debug|x64
17 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x64.Build.0 = Debug|x64
18 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x86.ActiveCfg = Debug|Win32
19 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Debug|x86.Build.0 = Debug|Win32
20 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x64.ActiveCfg = Release|x64
21 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x64.Build.0 = Release|x64
22 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x86.ActiveCfg = Release|Win32
23 | {EC2C0AF4-6D7E-401B-8E6C-534CB2A28945}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {1EE34913-FC21-43DC-A88E-DC625C27180E}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Assembly Language Snake Game
2 | ## About the project
3 | This program is a personal project when I was learning 'computer organization and architecture' in the second year of my Management Mathematics and Computing bachelors degree. The idea behind of this program was the classic "Snake" game. This program was made using Microsoft Visual Studio 2017's 32bit MASM architecture in protected mode (no interrupts) and the Irvine32 library.
4 |
5 | ## Features and Functions
6 | #### Game Speed Selection
7 | * User may choose from three speed levels, level 1 to level 3, level 3 being the slowest.
8 | * Each of the speed levels have a 40ms difference.
9 | #### Random Generation of coin
10 | * A coin is generated randomly at the start of every game or when the snake eats the previous coin.
11 | * A checking function is also created to make sure that the random coin doesnt generate on the coordinates of the snake.
12 | * A new coin is regenerated if the current one is generated at an invalid coordinate.
13 | #### Accepting keyboard input
14 | * After the coin is generated, a loop will be initiated to detect for input and jump to specific functions according to the input.
15 | * If no key is entered, the program will keep looping and waiting for an input.
16 | * If the snake is moving and a valid input is not entered, the function will continuously loop and snake will continuous to move at the current direction.
17 | * If the user enters a new input that moves the snake in a different direction, the program will jump to a function that changes the function of the snake.
18 | #### Move Snake
19 | * The head of the snake will be moved according to the user's last known input.
20 | * The body of the snake will be moved to the coordinate of the unit before it (eg: the 3rd unit of the body will move to the coordinates of the 2nd unit of the body)
21 | #### Coin Detection
22 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake eats a coin
23 | #### Eat Coin
24 | * When a coin is eaten, a new unit is added to the snake to lengthen the snake.
25 | * The new tail is at the position of the old tail, a new tail is added according to the direction of the old tail
26 | #### Self Collision Detection
27 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake collides with itself
28 | * Snake dies when it collides with itself
29 | * A function loops through the coordinates of the body of the snake and compares with the head position to check if they collide.
30 | #### Wall Collision Detection
31 | * When the Snake moves, the coordinate of the head is compared with the coordinate of the coin to check whether the snake collides with the wall
32 | * Snake dies when it collides with the wall
33 | * A function compares the coordinates of the wall and the head to check if they collide
34 | #### Scoreboard
35 | * When the game is over, a scoreboard is displayed to show the current score and high score of the user.
36 | * The user can also choose to exit the game or restart the game.
37 | #### Input Validation
38 | * Input Validation is set to detect any invalid input and prompts the user to reenter the input if so.
39 |
40 | ## Flowchart
41 | Flowchart of this program can be downloaded here: [snake game flowchart.pdf](https://github.com/meixinchoy/SnakeGame-asm8086/files/6953798/snake.game.flowchart.pdf)
42 |
43 | ## Controls
44 | | Keys | Actions |
45 | | ----------------- | --------------------------- |
46 | | w | Move up |
47 | | a | Move left |
48 | | s | Move down |
49 | | d | Move right |
50 | | x | Quits the game at any time |
51 | | enter | Pause, (w,a,s,d to unpause) |
52 |
53 | (make sure that your capslock is disabled)
54 |
55 | ## Screenshots
56 | 
57 |
58 | 
59 |
60 | 
61 |
62 | ## Installation
63 | To start the game you will need to install the following items:
64 | 1. visual studios (can be installed [here](https://visualstudio.microsoft.com/downloads/))
65 | 2. Irvine32 library (can be downloaded [here](https://github.com/meixinchoy/Irvine-library))
66 | 3. configure asm file, paste code in and run program
67 |
68 | ## Additional Notes
69 | Although the program code for the master branch and the adv branch slightly differs from each other, both codes are completed and able to output and run the full program. The master branch is more basic and easier to understand whereas the code in the develop branch more compact and the end screen displays the high score as well. Feel free to check out both versions of my program.
70 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/main.asm/main.asm/main.asm.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 15.0
23 | {ec2c0af4-6d7e-401b-8e6c-534cb2a28945}
24 | main_asm
25 | 10.0.17763.0
26 | main.asm
27 |
28 |
29 |
30 | Application
31 | true
32 | v141
33 | MultiByte
34 |
35 |
36 | Application
37 | false
38 | v141
39 | true
40 | MultiByte
41 |
42 |
43 | Application
44 | true
45 | v141
46 | MultiByte
47 |
48 |
49 | Application
50 | false
51 | v141
52 | true
53 | MultiByte
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | Level3
78 | Disabled
79 | true
80 | true
81 |
82 |
83 | Console
84 | c:\Irvine
85 | Irvine32.lib;%(AdditionalDependencies)
86 |
87 |
88 | c:\Irvine
89 |
90 |
91 |
92 |
93 | Level3
94 | Disabled
95 | true
96 | true
97 |
98 |
99 | Console
100 |
101 |
102 |
103 |
104 | Level3
105 | MaxSpeed
106 | true
107 | true
108 | true
109 | true
110 |
111 |
112 | Console
113 | true
114 | true
115 |
116 |
117 |
118 |
119 | Level3
120 | MaxSpeed
121 | true
122 | true
123 | true
124 | true
125 |
126 |
127 | Console
128 | true
129 | true
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/main.asm/main.asm/main.asm:
--------------------------------------------------------------------------------
1 | .386
2 | .model flat, stdcall
3 | .stack 4096
4 | ExitProcess PROTO, dwExitCode: DWORD
5 | INCLUDE Irvine32.inc
6 |
7 | .data
8 |
9 | xWall BYTE 52 DUP("#"),0
10 |
11 | strScore BYTE "Your score is: ",0
12 | score BYTE 0
13 |
14 | strTryAgain BYTE "Try Again? 1=yes, 0=no",0
15 | invalidInput BYTE "invalid input",0
16 | strYouDied BYTE "you died ",0
17 | strPoints BYTE " point(s)",0
18 | blank BYTE " ",0
19 |
20 | snake BYTE "X", 104 DUP("x")
21 |
22 | xPos BYTE 45,44,43,42,41, 100 DUP(?)
23 | yPos BYTE 15,15,15,15,15, 100 DUP(?)
24 |
25 | xPosWall BYTE 34,34,85,85 ;position of upperLeft, lowerLeft, upperRight, lowerRignt wall
26 | yPosWall BYTE 5,24,5,24
27 |
28 | xCoinPos BYTE ?
29 | yCoinPos BYTE ?
30 |
31 | inputChar BYTE "+" ; + denotes the start of the game
32 | lastInputChar BYTE ?
33 |
34 | strSpeed BYTE "Speed (1-fast, 2-medium, 3-slow): ",0
35 | speed DWORD 0
36 |
37 | .code
38 | main PROC
39 | call DrawWall ;draw walls
40 | call DrawScoreboard ;draw scoreboard
41 | call ChooseSpeed ;let player to choose Speed
42 |
43 | mov esi,0
44 | mov ecx,5
45 | drawSnake:
46 | call DrawPlayer ;draw snake(start with 5 units)
47 | inc esi
48 | loop drawSnake
49 |
50 | call Randomize
51 | call CreateRandomCoin
52 | call DrawCoin ;set up finish
53 |
54 | gameLoop::
55 | mov dl,106 ;move cursor to coordinates
56 | mov dh,1
57 | call Gotoxy
58 |
59 | ; get user key input
60 | call ReadKey
61 | jz noKey ;jump if no key is entered
62 | processInput:
63 | mov bl, inputChar
64 | mov lastInputChar, bl
65 | mov inputChar,al ;assign variables
66 |
67 | noKey:
68 | cmp inputChar,"x"
69 | je exitgame ;exit game if user input x
70 |
71 | cmp inputChar,"w"
72 | je checkTop
73 |
74 | cmp inputChar,"s"
75 | je checkBottom
76 |
77 | cmp inputChar,"a"
78 | je checkLeft
79 |
80 | cmp inputChar,"d"
81 | je checkRight
82 | jne gameLoop ; reloop if no meaningful key was entered
83 |
84 |
85 | ; check whether can continue moving
86 | checkBottom:
87 | cmp lastInputChar, "w"
88 | je dontChgDirection ;cant go down immediately after going up
89 | mov cl, yPosWall[1]
90 | dec cl ;one unit ubove the y-coordinate of the lower bound
91 | cmp yPos[0],cl
92 | jl moveDown
93 | je died ;die if crash into the wall
94 |
95 | checkLeft:
96 | cmp lastInputChar, "+" ;check whether its the start of the game
97 | je dontGoLeft
98 | cmp lastInputChar, "d"
99 | je dontChgDirection
100 | mov cl, xPosWall[0]
101 | inc cl
102 | cmp xPos[0],cl
103 | jg moveLeft
104 | je died ; check for left
105 |
106 | checkRight:
107 | cmp lastInputChar, "a"
108 | je dontChgDirection
109 | mov cl, xPosWall[2]
110 | dec cl
111 | cmp xPos[0],cl
112 | jl moveRight
113 | je died ; check for right
114 |
115 | checkTop:
116 | cmp lastInputChar, "s"
117 | je dontChgDirection
118 | mov cl, yPosWall[0]
119 | inc cl
120 | cmp yPos,cl
121 | jg moveUp
122 | je died ; check for up
123 |
124 | moveUp:
125 | mov eax, speed ;slow down the moving
126 | add eax, speed
127 | call delay
128 | mov esi, 0 ;index 0(snake head)
129 | call UpdatePlayer
130 | mov ah, yPos[esi]
131 | mov al, xPos[esi] ;alah stores the pos of the snake's next unit
132 | dec yPos[esi] ;move the head up
133 | call DrawPlayer
134 | call DrawBody
135 | call CheckSnake
136 |
137 |
138 | moveDown: ;move down
139 | mov eax, speed
140 | add eax, speed
141 | call delay
142 | mov esi, 0
143 | call UpdatePlayer
144 | mov ah, yPos[esi]
145 | mov al, xPos[esi]
146 | inc yPos[esi]
147 | call DrawPlayer
148 | call DrawBody
149 | call CheckSnake
150 |
151 |
152 | moveLeft: ;move left
153 | mov eax, speed
154 | call delay
155 | mov esi, 0
156 | call UpdatePlayer
157 | mov ah, yPos[esi]
158 | mov al, xPos[esi]
159 | dec xPos[esi]
160 | call DrawPlayer
161 | call DrawBody
162 | call CheckSnake
163 |
164 |
165 | moveRight: ;move right
166 | mov eax, speed
167 | call delay
168 | mov esi, 0
169 | call UpdatePlayer
170 | mov ah, yPos[esi]
171 | mov al, xPos[esi]
172 | inc xPos[esi]
173 | call DrawPlayer
174 | call DrawBody
175 | call CheckSnake
176 |
177 | ; getting points
178 | checkcoin::
179 | mov esi,0
180 | mov bl,xPos[0]
181 | cmp bl,xCoinPos
182 | jne gameloop ;reloop if snake is not intersecting with coin
183 | mov bl,yPos[0]
184 | cmp bl,yCoinPos
185 | jne gameloop ;reloop if snake is not intersecting with coin
186 |
187 | call EatingCoin ;call to update score, append snake and generate new coin
188 |
189 | jmp gameLoop ;reiterate the gameloop
190 |
191 |
192 | dontChgDirection: ;dont allow user to change direction
193 | mov inputChar, bl ;set current inputChar as previous
194 | jmp noKey ;jump back to continue moving the same direction
195 |
196 | dontGoLeft: ;forbids the snake to go left at the begining of the game
197 | mov inputChar, "+" ;set current inputChar as "+"
198 | jmp gameLoop ;restart the game loop
199 |
200 | died::
201 | call YouDied
202 |
203 | playagn::
204 | call ReinitializeGame ;reinitialise everything
205 |
206 | exitgame::
207 | exit
208 | INVOKE ExitProcess,0
209 | main ENDP
210 |
211 |
212 | DrawWall PROC ;procedure to draw wall
213 | mov dl,xPosWall[0]
214 | mov dh,yPosWall[0]
215 | call Gotoxy
216 | mov edx,OFFSET xWall
217 | call WriteString ;draw upper wall
218 |
219 | mov dl,xPosWall[1]
220 | mov dh,yPosWall[1]
221 | call Gotoxy
222 | mov edx,OFFSET xWall
223 | call WriteString ;draw lower wall
224 |
225 | mov dl, xPosWall[2]
226 | mov dh, yPosWall[2]
227 | mov eax,"#"
228 | inc yPosWall[3]
229 | L11:
230 | call Gotoxy
231 | call WriteChar
232 | inc dh
233 | cmp dh, yPosWall[3] ;draw right wall
234 | jl L11
235 |
236 | mov dl, xPosWall[0]
237 | mov dh, yPosWall[0]
238 | mov eax,"#"
239 | L12:
240 | call Gotoxy
241 | call WriteChar
242 | inc dh
243 | cmp dh, yPosWall[3] ;draw left wall
244 | jl L12
245 | ret
246 | DrawWall ENDP
247 |
248 |
249 | DrawScoreboard PROC ;procedure to draw scoreboard
250 | mov dl,2
251 | mov dh,1
252 | call Gotoxy
253 | mov edx,OFFSET strScore ;print string that indicates score
254 | call WriteString
255 | mov eax,"0"
256 | call WriteChar ;scoreboard starts with 0
257 | ret
258 | DrawScoreboard ENDP
259 |
260 |
261 | ChooseSpeed PROC ;procedure for player to choose speed
262 | mov edx,0
263 | mov dl,71
264 | mov dh,1
265 | call Gotoxy
266 | mov edx,OFFSET strSpeed ; prompt to enter integers (1,2,3)
267 | call WriteString
268 | mov esi, 40 ; milisecond difference per speed level
269 | mov eax,0
270 | call readInt
271 | cmp ax,1 ;input validation
272 | jl invalidspeed
273 | cmp ax, 3
274 | jg invalidspeed
275 | mul esi
276 | mov speed, eax ;assign speed variable in mililiseconds
277 | ret
278 |
279 | invalidspeed: ;jump here if user entered an invalid number
280 | mov dl,105
281 | mov dh,1
282 | call Gotoxy
283 | mov edx, OFFSET invalidInput ;print error message
284 | call WriteString
285 | mov ax, 1500
286 | call delay
287 | mov dl,105
288 | mov dh,1
289 | call Gotoxy
290 | mov edx, OFFSET blank ;erase error message after 1.5 secs of delay
291 | call writeString
292 | call ChooseSpeed ;call procedure for user to choose again
293 | ret
294 | ChooseSpeed ENDP
295 |
296 | DrawPlayer PROC ; draw player at (xPos,yPos)
297 | mov dl,xPos[esi]
298 | mov dh,yPos[esi]
299 | call Gotoxy
300 | mov dl, al ;temporarily save al in dl
301 | mov al, snake[esi]
302 | call WriteChar
303 | mov al, dl
304 | ret
305 | DrawPlayer ENDP
306 |
307 | UpdatePlayer PROC ; erase player at (xPos,yPos)
308 | mov dl, xPos[esi]
309 | mov dh,yPos[esi]
310 | call Gotoxy
311 | mov dl, al ;temporarily save al in dl
312 | mov al, " "
313 | call WriteChar
314 | mov al, dl
315 | ret
316 | UpdatePlayer ENDP
317 |
318 | DrawCoin PROC ;procedure to draw coin
319 | mov eax,yellow (yellow * 16)
320 | call SetTextColor ;set color to yellow for coin
321 | mov dl,xCoinPos
322 | mov dh,yCoinPos
323 | call Gotoxy
324 | mov al,"X"
325 | call WriteChar
326 | mov eax,white (black * 16) ;reset color to black and white
327 | call SetTextColor
328 | ret
329 | DrawCoin ENDP
330 |
331 | CreateRandomCoin PROC ;procedure to create a random coin
332 | mov eax,49
333 | call RandomRange ;0-49
334 | add eax, 35 ;35-84
335 | mov xCoinPos,al
336 | mov eax,17
337 | call RandomRange ;0-17
338 | add eax, 6 ;6-23
339 | mov yCoinPos,al
340 |
341 | mov ecx, 5
342 | add cl, score ;loop number of snake unit
343 | mov esi, 0
344 | checkCoinXPos:
345 | movzx eax, xCoinPos
346 | cmp al, xPos[esi]
347 | je checkCoinYPos ;jump if xPos of snake at esi = xPos of coin
348 | continueloop:
349 | inc esi
350 | loop checkCoinXPos
351 | ret ; return when coin is not on snake
352 | checkCoinYPos:
353 | movzx eax, yCoinPos
354 | cmp al, yPos[esi]
355 | jne continueloop ; jump back to continue loop if yPos of snake at esi != yPos of coin
356 | call CreateRandomCoin ; coin generated on snake, calling function again to create another set of coordinates
357 | CreateRandomCoin ENDP
358 |
359 | CheckSnake PROC ;check whether the snake head collides w its body
360 | mov al, xPos[0]
361 | mov ah, yPos[0]
362 | mov esi,4 ;start checking from index 4(5th unit)
363 | mov ecx,1
364 | add cl,score
365 | checkXposition:
366 | cmp xPos[esi], al ;check if xpos same ornot
367 | je XposSame
368 | contloop:
369 | inc esi
370 | loop checkXposition
371 | jmp checkcoin
372 | XposSame: ; if xpos same, check for ypos
373 | cmp yPos[esi], ah
374 | je died ;if collides, snake dies
375 | jmp contloop
376 |
377 | CheckSnake ENDP
378 |
379 | DrawBody PROC ;procedure to print body of the snake
380 | mov ecx, 4
381 | add cl, score ;number of iterations to print the snake body n tail
382 | printbodyloop:
383 | inc esi ;loop to print remaining units of snake
384 | call UpdatePlayer
385 | mov dl, xPos[esi]
386 | mov dh, yPos[esi] ;dldh temporarily stores the current pos of the unit
387 | mov yPos[esi], ah
388 | mov xPos[esi], al ;assign new position to the unit
389 | mov al, dl
390 | mov ah,dh ;move the current position back into alah
391 | call DrawPlayer
392 | cmp esi, ecx
393 | jl printbodyloop
394 | ret
395 | DrawBody ENDP
396 |
397 | EatingCoin PROC
398 | ; snake is eating coin
399 | inc score
400 | mov ebx,4
401 | add bl, score
402 | mov esi, ebx
403 | mov ah, yPos[esi-1]
404 | mov al, xPos[esi-1]
405 | mov xPos[esi], al ;add one unit to the snake
406 | mov yPos[esi], ah ;pos of new tail = pos of old tail
407 |
408 | cmp xPos[esi-2], al ;check if the old tail and the unit before is on the yAxis
409 | jne checky ;jump if not on the yAxis
410 |
411 | cmp yPos[esi-2], ah ;check if the new tail should be above or below of the old tail
412 | jl incy
413 | jg decy
414 | incy: ;inc if below
415 | inc yPos[esi]
416 | jmp continue
417 | decy: ;dec if above
418 | dec yPos[esi]
419 | jmp continue
420 |
421 | checky: ;old tail and the unit before is on the xAxis
422 | cmp yPos[esi-2], ah ;check if the new tail should be right or left of the old tail
423 | jl incx
424 | jg decx
425 | incx: ;inc if right
426 | inc xPos[esi]
427 | jmp continue
428 | decx: ;dec if left
429 | dec xPos[esi]
430 |
431 | continue: ;add snake tail and update new coin
432 | call DrawPlayer
433 | call CreateRandomCoin
434 | call DrawCoin
435 |
436 | mov dl,17 ; write updated score
437 | mov dh,1
438 | call Gotoxy
439 | mov al,score
440 | call WriteInt
441 | ret
442 | EatingCoin ENDP
443 |
444 |
445 | YouDied PROC
446 | mov eax, 1000
447 | call delay
448 | Call ClrScr
449 |
450 | mov dl, 57
451 | mov dh, 12
452 | call Gotoxy
453 | mov edx, OFFSET strYouDied ;"you died"
454 | call WriteString
455 |
456 | mov dl, 56
457 | mov dh, 14
458 | call Gotoxy
459 | movzx eax, score
460 | call WriteInt
461 | mov edx, OFFSET strPoints ;display score
462 | call WriteString
463 |
464 | mov dl, 50
465 | mov dh, 18
466 | call Gotoxy
467 | mov edx, OFFSET strTryAgain
468 | call WriteString ;"try again?"
469 |
470 | retry:
471 | mov dh, 19
472 | mov dl, 56
473 | call Gotoxy
474 | call ReadInt ;get user input
475 | cmp al, 1
476 | je playagn ;playagn
477 | cmp al, 0
478 | je exitgame ;exitgame
479 |
480 | mov dh, 17
481 | call Gotoxy
482 | mov edx, OFFSET invalidInput ;"Invalid input"
483 | call WriteString
484 | mov dl, 56
485 | mov dh, 19
486 | call Gotoxy
487 | mov edx, OFFSET blank ;erase previous input
488 | call WriteString
489 | jmp retry ;let user input again
490 | YouDied ENDP
491 |
492 | ReinitializeGame PROC ;procedure to reinitialize everything
493 | mov xPos[0], 45
494 | mov xPos[1], 44
495 | mov xPos[2], 43
496 | mov xPos[3], 42
497 | mov xPos[4], 41
498 | mov yPos[0], 15
499 | mov yPos[1], 15
500 | mov yPos[2], 15
501 | mov yPos[3], 15
502 | mov yPos[4], 15 ;reinitialize snake position
503 | mov score,0 ;reinitialize score
504 | mov lastInputChar, 0
505 | mov inputChar, "+" ;reinitialize inputChar and lastInputChar
506 | dec yPosWall[3] ;reset wall position
507 | Call ClrScr
508 | jmp main ;start over the game
509 | ReinitializeGame ENDP
510 | END main
--------------------------------------------------------------------------------