Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
aostap
/
ussimang
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Merge Requests
0
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
bedf0794
authored
May 01, 2023
by
aostap
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ussimängu kood
parent
05d21e0c
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
677 additions
and
0 deletions
USSIKE.c
USSIKE.c
0 → 100644
View file @
bedf0794
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ncurses.h>
#include <time.h>
#define ROWS 20
#define COLS 45
#define MENU_ROWS 25
#define START_LENGTH 1
#define MAX_LENGTH 900
#define MAX_SPAWNS 900
#define STRUCT_LEN 64
#define MAX_SCORES 1000
#define GAME_WIN_SCORE 900000
#define SCORE_OUTPUT_MAX 3
#define FOOD_CHAR 'O'
#define STOP 0
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
typedef
struct
{
int
x
,
y
;
}
position
;
int
fieldX
,
fieldY
;
int
fX
,
fY
;
WINDOW
*
field
;
void
Colors
();
void
MenuWindow
();
void
SnakeGame
();
void
SnakeStartingPosition
(
int
*
x
,
int
*
y
,
position
*
snake
);
void
SpawnApple
(
int
*
fx
,
int
*
fy
,
position
*
apple
,
position
*
snake
,
int
length
);
void
GrowSnake
(
position
*
snake
,
int
n
);
void
ReadScores
(
int
max
,
int
a
,
WINDOW
*
score
,
int
center
);
void
PrintScore
(
int
score
);
void
ScoreWindow
();
void
LiveScoreWindow
(
int
score
);
void
PrintLiveScore
(
int
score
);
void
PlaceBackBlocks
(
position
*
snake
,
int
n
);
void
MoveSnakeHead
(
int
x
,
int
y
,
position
*
snake
);
bool
CheckSelfCollision
(
position
*
snake
,
int
length
);
bool
CheckBorderCollision
(
position
*
snake
);
void
RemoveSnakeTail
(
position
*
snake
,
int
n
);
void
UpdateSnake_Apple
(
position
*
apple
,
position
*
snake
,
int
n
);
_Bool
EmptyCoordinates
(
int
*
fx
,
int
*
fy
,
position
*
snake
,
int
n
);
bool
gameover
=
false
;
void
Setup
()
{
// initialize ncurses
initscr
();
// enable colors
start_color
();
Colors
();
// disable line buffering, allow each keystroke to be processed immediately
cbreak
();
// don't echo user input to the screen
noecho
();
srand
(
time
(
NULL
));
// remove cursor
curs_set
(
0
);
}
void
Colors
()
{
init_pair
(
1
,
COLOR_GREEN
,
COLOR_GREEN
);
// snake color
init_pair
(
2
,
COLOR_RED
,
COLOR_RED
);
// apple color
init_pair
(
3
,
COLOR_GREEN
,
COLOR_BLACK
);
// green ascii snake
init_pair
(
4
,
COLOR_RED
,
COLOR_BLACK
);
// red borders
init_pair
(
5
,
COLOR_WHITE
,
COLOR_BLACK
);
// white text
init_pair
(
6
,
COLOR_WHITE
,
COLOR_WHITE
);
// gray borders
}
void
Menu
()
{
MenuWindow
();
// counter for default
int
count
=
0
;
while
(
count
<=
0
)
{
int
input
=
getch
();
switch
(
input
)
{
case
's'
:
SnakeGame
();
count
++
;
break
;
case
'h'
:
ScoreWindow
();
count
++
;
break
;
case
'q'
:
count
++
;
break
;
default:
break
;
}
}
}
void
MenuWindow
()
{
clear
();
refresh
();
int
xMax
,
yMax
;
getmaxyx
(
stdscr
,
yMax
,
xMax
);
WINDOW
*
menu
=
newwin
(
yMax
/
2
,
xMax
/
2
,
yMax
/
4
,
xMax
/
4
);
box
(
menu
,
0
,
0
);
int
center
=
xMax
/
4
;
wattron
(
menu
,
COLOR_PAIR
(
5
));
mvwprintw
(
menu
,
1
,
center
-
10
,
"WELCOME TO SNAKE GAME!"
);
mvwprintw
(
menu
,
3
,
center
-
12
,
"PRESS 's' TO PLAY SNAKE GAME"
);
mvwprintw
(
menu
,
4
,
center
-
12
,
"PRESS 'h' TO VIEW HIGH SCORES"
);
mvwprintw
(
menu
,
5
,
center
-
12
,
"PRESS 'q' TO QUIT"
);
wattroff
(
menu
,
COLOR_PAIR
(
5
));
wattron
(
menu
,
COLOR_PAIR
(
3
));
mvwprintw
(
menu
,
5
,
center
-
MENU_ROWS
,
" Y"
);
mvwprintw
(
menu
,
6
,
center
-
MENU_ROWS
,
" .-^-."
);
mvwprintw
(
menu
,
7
,
center
-
MENU_ROWS
,
" /
\\
.- ~ ~ -."
);
mvwprintw
(
menu
,
8
,
center
-
MENU_ROWS
,
"() () / _ _ `. _ _ _"
);
mvwprintw
(
menu
,
9
,
center
-
MENU_ROWS
,
"
\\
_ _/ / /
\\
\\
. ~ _ _ ~ ."
);
mvwprintw
(
menu
,
10
,
center
-
MENU_ROWS
,
" | | / /
\\
\\
.' .~ ~-. `."
);
mvwprintw
(
menu
,
11
,
center
-
MENU_ROWS
,
" | | / / ) ) / / `.`."
);
mvwprintw
(
menu
,
12
,
center
-
MENU_ROWS
,
"
\\
\\
_ _/ / / / / / `'"
);
mvwprintw
(
menu
,
13
,
center
-
MENU_ROWS
,
"
\\
_ _ _.' / / ( ("
);
mvwprintw
(
menu
,
14
,
center
-
MENU_ROWS
,
" / /
\\
\\
"
);
mvwprintw
(
menu
,
15
,
center
-
MENU_ROWS
,
" / /
\\
\\
"
);
mvwprintw
(
menu
,
16
,
center
-
MENU_ROWS
,
" / / ) )"
);
mvwprintw
(
menu
,
17
,
center
-
MENU_ROWS
,
" ( ( / /"
);
mvwprintw
(
menu
,
18
,
center
-
MENU_ROWS
,
" `. `. .' /"
);
mvwprintw
(
menu
,
19
,
center
-
MENU_ROWS
,
" `. ~ - - - - ~ .'"
);
mvwprintw
(
menu
,
20
,
center
-
MENU_ROWS
,
" ~ . _ _ _ _ . ~"
);
wattroff
(
menu
,
COLOR_PAIR
(
3
));
// end green snake
wattron
(
menu
,
COLOR_PAIR
(
4
));
// red borders
wborder
(
menu
,
'|'
,
'|'
,
'-'
,
'-'
,
'+'
,
'+'
,
'+'
,
'+'
);
wattroff
(
menu
,
COLOR_PAIR
(
4
));
// end red borders
wrefresh
(
menu
);
}
void
ScoreWindow
(
WINDOW
*
score
,
int
center
)
{
clear
();
refresh
();
int
xMax
,
yMax
;
getmaxyx
(
stdscr
,
yMax
,
xMax
);
score
=
newwin
(
yMax
/
2
,
xMax
/
2
,
yMax
/
4
,
xMax
/
4
);
box
(
score
,
0
,
0
);
center
=
xMax
/
4
;
mvwprintw
(
score
,
5
,
center
-
7
,
"HIGH SCORE!!!"
);
ReadScores
(
MAX_SCORES
,
0
,
score
,
center
);
mvwprintw
(
score
,
8
,
center
-
8
,
"LAST THREE SCORES:"
);
ReadScores
(
MAX_SCORES
,
1
,
score
,
center
);
mvwprintw
(
score
,
15
,
center
-
10
,
"PRESS 'b' TO GO BACK"
);
wattron
(
score
,
COLOR_PAIR
(
4
));
// red borders
wborder
(
score
,
'|'
,
'|'
,
'-'
,
'-'
,
'+'
,
'+'
,
'+'
,
'+'
);
wattroff
(
score
,
COLOR_PAIR
(
4
));
// end red borders
wrefresh
(
score
);
// counter for default
int
count
=
0
;
while
(
count
<=
0
)
{
int
input
=
getch
();
switch
(
input
)
{
case
'b'
:
Menu
();
count
++
;
break
;
default:
refresh
();
break
;
}
}
}
void
Gamefield
()
{
clear
();
refresh
();
int
xMax
,
yMax
;
getmaxyx
(
stdscr
,
yMax
,
xMax
);
fieldY
=
(
yMax
/
2
)
-
(
ROWS
/
2
);
fieldX
=
(
xMax
/
2
)
-
(
COLS
/
2
);
fX
=
(
yMax
/
2
)
+
(
ROWS
/
2
);
fY
=
(
xMax
/
2
)
+
(
COLS
/
2
);
field
=
newwin
(
ROWS
,
COLS
,
fieldY
,
fieldX
);
box
(
field
,
0
,
0
);
nodelay
(
field
,
TRUE
);
wattron
(
field
,
COLOR_PAIR
(
6
));
// white borders
wborder
(
field
,
'|'
,
'|'
,
'-'
,
'-'
,
'+'
,
'+'
,
'+'
,
'+'
);
wattroff
(
field
,
COLOR_PAIR
(
6
));
// end white borders
wrefresh
(
field
);
}
void
LiveScoreWindow
(
int
score
)
{
clear
();
refresh
();
int
xMax
,
yMax
;
getmaxyx
(
stdscr
,
yMax
,
xMax
);
WINDOW
*
scoreWindow
=
newwin
(
yMax
/
2
,
xMax
/
2
,
yMax
/
4
,
xMax
/
4
);
box
(
scoreWindow
,
0
,
0
);
int
center
=
xMax
/
4
;
mvwprintw
(
scoreWindow
,
3
,
center
-
6
,
"SCORE"
);
mvwprintw
(
scoreWindow
,
3
,
center
,
"%d"
,
score
);
mvwprintw
(
scoreWindow
,
5
,
center
-
10
,
"PRESS 'y' TO PLAY AGAIN"
);
mvwprintw
(
scoreWindow
,
6
,
center
-
10
,
"PRESS 'n' TO GO TO MENU"
);
wattron
(
scoreWindow
,
COLOR_PAIR
(
4
));
// red borders
wborder
(
scoreWindow
,
'|'
,
'|'
,
'-'
,
'-'
,
'+'
,
'+'
,
'+'
,
'+'
);
wattroff
(
scoreWindow
,
COLOR_PAIR
(
4
));
// end red borders
// Refresh windows
refresh
();
wrefresh
(
field
);
wrefresh
(
scoreWindow
);
// counter for default
int
count
=
0
;
while
(
count
<=
0
)
{
int
input
=
getch
();
switch
(
input
)
{
case
'y'
:
gameover
=
false
;
SnakeGame
();
count
++
;
break
;
case
'n'
:
Menu
();
count
++
;
break
;
default:
break
;
}
}
}
void
GameWon
()
{
clear
();
refresh
();
int
xMax
,
yMax
;
getmaxyx
(
stdscr
,
yMax
,
xMax
);
WINDOW
*
scoreWindow
=
newwin
(
yMax
/
2
,
xMax
/
2
,
yMax
/
4
,
xMax
/
4
);
box
(
scoreWindow
,
0
,
0
);
int
center
=
xMax
/
4
;
mvwprintw
(
scoreWindow
,
5
,
center
-
10
,
"GAME WON!"
);
mvwprintw
(
scoreWindow
,
7
,
center
-
10
,
"PRESS 'y' TO PLAY AGAIN"
);
mvwprintw
(
scoreWindow
,
8
,
center
-
10
,
"PRESS 'n' TO GO TO MENU"
);
wattron
(
scoreWindow
,
COLOR_PAIR
(
4
));
// red borders
wborder
(
scoreWindow
,
'|'
,
'|'
,
'-'
,
'-'
,
'+'
,
'+'
,
'+'
,
'+'
);
wattroff
(
scoreWindow
,
COLOR_PAIR
(
4
));
// end red borders
// Refresh windows
refresh
();
wrefresh
(
field
);
wrefresh
(
scoreWindow
);
// counter for default
int
count
=
0
;
while
(
count
<=
0
)
{
int
input
=
getch
();
switch
(
input
)
{
case
'y'
:
gameover
=
false
;
SnakeGame
();
count
++
;
break
;
case
'n'
:
Menu
();
count
++
;
break
;
default:
break
;
}
}
}
void
SnakeGame
()
{
Gamefield
();
position
snake
[
MAX_LENGTH
];
position
apple
[
MAX_SPAWNS
];
gameover
=
false
;
int
length
;
int
direction
;
// snake coordinates
int
x
,
y
;
// apple coordinates
int
fx
,
fy
;
int
score
=
0
;
// Time delay for snake movement
struct
timespec
sleep_time
;
sleep_time
.
tv_sec
=
0
;
sleep_time
.
tv_nsec
=
100000000
;
length
=
START_LENGTH
;
// Inital direction waits for user input
direction
=
STOP
;
// Snake starting point
SnakeStartingPosition
(
&
x
,
&
y
,
snake
);
// Apple starting point and spawns in apples
SpawnApple
(
&
fx
,
&
fy
,
apple
,
snake
,
length
);
while
(
!
gameover
)
{
// Get user input
int
input
=
wgetch
(
field
);
switch
(
input
)
{
case
'a'
:
if
(
direction
!=
RIGHT
)
{
direction
=
LEFT
;
}
break
;
case
'd'
:
if
(
direction
!=
LEFT
)
{
direction
=
RIGHT
;
}
break
;
case
'w'
:
if
(
direction
!=
DOWN
)
{
direction
=
UP
;
}
break
;
case
's'
:
if
(
direction
!=
UP
)
{
direction
=
DOWN
;
}
break
;
// Pause game
case
'p'
:
while
(
getch
()
!=
'p'
);
break
;
// Exit game
case
'q'
:
gameover
=
true
;
break
;
default:
break
;
}
// Input Logic
switch
(
direction
)
{
case
UP
:
y
--
;
break
;
case
DOWN
:
y
++
;
break
;
case
LEFT
:
x
--
;
break
;
case
RIGHT
:
x
++
;
break
;
}
// Check if apple has been eaten
if
(
x
==
fx
&&
y
==
fy
)
{
GrowSnake
(
snake
,
length
);
length
++
;
score
+=
100
;
SpawnApple
(
&
fx
,
&
fy
,
apple
,
snake
,
length
);
}
else
{
RemoveSnakeTail
(
snake
,
length
);
}
PlaceBackBlocks
(
snake
,
length
);
MoveSnakeHead
(
x
,
y
,
snake
);
// Game over situations
if
(
CheckBorderCollision
(
snake
))
{
gameover
=
true
;
LiveScoreWindow
(
score
);
}
if
(
CheckSelfCollision
(
snake
,
length
))
{
gameover
=
true
;
LiveScoreWindow
(
score
);
}
PrintLiveScore
(
score
);
UpdateSnake_Apple
(
apple
,
snake
,
length
);
refresh
();
nanosleep
(
&
sleep_time
,
NULL
);
// Game is won
if
(
score
>=
GAME_WIN_SCORE
)
{
GameWon
();
score
=
0
;
}
}
PrintScore
(
score
);
}
void
SnakeStartingPosition
(
int
*
x
,
int
*
y
,
position
*
snake
)
{
*
x
=
rand
()
%
(
COLS
-
2
)
+
fieldX
+
1
;
*
y
=
rand
()
%
(
ROWS
-
2
)
+
fieldY
+
1
;
snake
[
0
].
x
=
*
x
;
snake
[
0
].
y
=
*
y
;
}
void
SpawnApple
(
int
*
fx
,
int
*
fy
,
position
*
apple
,
position
*
snake
,
int
length
)
{
do
{
*
fx
=
rand
()
%
(
COLS
-
2
)
+
fieldX
+
1
;
*
fy
=
rand
()
%
(
ROWS
-
2
)
+
fieldY
+
1
;
apple
[
0
].
x
=
*
fx
;
apple
[
0
].
y
=
*
fy
;
}
while
(
!
EmptyCoordinates
(
fx
,
fy
,
snake
,
length
));
}
_Bool
EmptyCoordinates
(
int
*
fx
,
int
*
fy
,
position
*
snake
,
int
n
)
{
// Check if the coordinates are occupied by the snake
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
if
(
*
fx
==
snake
[
i
].
x
&&
*
fy
==
snake
[
i
].
y
)
{
return
FALSE
;
}
}
return
TRUE
;
}
void
GrowSnake
(
position
*
snake
,
int
n
)
{
snake
[
n
].
x
=
snake
[
n
-
1
].
x
;
snake
[
n
].
y
=
snake
[
n
-
1
].
y
;
}
void
MoveSnakeHead
(
int
x
,
int
y
,
position
*
snake
)
{
snake
[
0
].
x
=
x
;
snake
[
0
].
y
=
y
;
}
bool
CheckSelfCollision
(
position
*
snake
,
int
length
)
{
for
(
int
i
=
1
;
i
<
length
;
i
++
)
{
if
(
snake
[
i
].
x
==
snake
[
0
].
x
&&
snake
[
i
].
y
==
snake
[
0
].
y
)
{
return
true
;
}
}
return
false
;
}
bool
CheckBorderCollision
(
position
*
snake
)
{
// left border
if
(
snake
[
0
].
x
==
fieldX
)
{
return
true
;
}
// upper border
if
(
snake
[
0
].
y
==
fieldY
)
{
return
true
;
}
// lower border
if
(
snake
[
0
].
y
==
fieldY
+
ROWS
-
1
){
return
true
;
}
// right border
if
(
snake
[
0
].
x
==
fieldX
+
COLS
-
1
){
return
true
;
}
return
false
;
}
void
PlaceBackBlocks
(
position
*
snake
,
int
n
)
{
int
i
;
position
temp
;
for
(
i
=
n
;
i
>
0
;
i
--
)
{
temp
=
snake
[
i
-
1
];
snake
[
i
]
=
temp
;
}
}
void
RemoveSnakeTail
(
position
*
snake
,
int
n
)
{
mvaddch
(
snake
[
n
-
1
].
y
,
snake
[
n
-
1
].
x
,
' '
);
snake
[
n
-
1
].
x
=
-
1
;
snake
[
n
-
1
].
y
=
-
1
;
}
void
UpdateSnake_Apple
(
position
*
apple
,
position
*
snake
,
int
n
)
{
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
if
(
snake
[
i
].
y
!=
-
1
&&
snake
[
i
].
x
!=
-
1
)
{
attron
(
COLOR_PAIR
(
1
));
// set snake color
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
mvaddch
(
snake
[
i
].
y
,
snake
[
i
].
x
,
' '
|
A_REVERSE
);
}
attroff
(
COLOR_PAIR
(
1
));
// unset snake color
}
}
attron
(
COLOR_PAIR
(
2
));
// set food color
mvaddch
(
apple
->
y
,
apple
->
x
,
FOOD_CHAR
);
attroff
(
COLOR_PAIR
(
2
));
// unset food color
}
void
PrintLiveScore
(
int
score
)
{
mvprintw
(
fieldY
+
ROWS
,
fieldX
,
"SCORE"
);
mvprintw
(
fieldY
+
ROWS
,
fieldX
+
COLS
-
3
,
"%d"
,
score
);
}
void
PrintScore
(
int
score
)
{
FILE
*
fp
=
fopen
(
"scores.txt"
,
"a"
);
if
(
fp
==
NULL
)
{
printf
(
"Error opening file!
\n
"
);
}
time_t
currentTime
;
struct
tm
*
currentTimeStruct
;
time
(
&
currentTime
);
currentTimeStruct
=
localtime
(
&
currentTime
);
char
timeString
[
STRUCT_LEN
];
strftime
(
timeString
,
STRUCT_LEN
,
"%Y.%m.%d %H:%M:%S"
,
currentTimeStruct
);
fprintf
(
fp
,
"%s score: %d
\n
"
,
timeString
,
score
);
fclose
(
fp
);
}
void
ReadScores
(
int
max
,
int
a
,
WINDOW
*
score
,
int
center
)
{
FILE
*
fp
=
fopen
(
"scores.txt"
,
"r"
);
if
(
fp
==
NULL
)
{
printf
(
"Error opening file!
\n
"
);
}
int
last_scores
[
MAX_SCORES
];
int
i
=
0
;
int
count
=
0
;
while
(
fscanf
(
fp
,
"%*s %*s %*s %d"
,
&
last_scores
[
i
])
==
1
)
{
i
++
;
count
++
;
if
(
i
>=
max
)
{
printf
(
"Error! Count has reached the limit!
\n
"
);
break
;
}
if
(
count
==
0
)
{
printf
(
"No scores have yet been saved
\n
"
);
}
}
if
(
a
==
0
)
{
int
max_score
=
last_scores
[
0
];
// start with the first score
if
(
count
==
0
)
{
mvwprintw
(
score
,
6
,
center
-
10
,
"No scores have been saved!"
);
}
else
{
for
(
int
i
=
1
;
i
<
count
;
i
++
)
{
if
(
last_scores
[
i
]
>
max_score
)
{
max_score
=
last_scores
[
i
];
// update the max score if a higher score is found
}
}
mvwprintw
(
score
,
6
,
center
-
10
,
" %d
\n
"
,
max_score
);
}
}
else
{
if
(
count
==
0
)
{
mvwprintw
(
score
,
10
,
center
-
10
,
"No scores have been saved!"
);
}
else
{
int
j
=
0
;
for
(
i
=
count
-
1
;
i
>
0
&&
j
<
SCORE_OUTPUT_MAX
;
i
--
)
{
mvwprintw
(
score
,
10
+
j
,
center
-
10
,
" %d
\n
"
,
last_scores
[
i
]);
j
++
;
}
}
}
}
int
main
()
{
Setup
();
//SnakeGame();
Menu
();
//getch();
endwin
();
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment