-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
commit b0f2cd8 Author: focused_xy <[email protected]> Date: Sat Oct 26 21:39:23 2024 +0800 feat: week4 lecture 内容同 week4 note commit f3df13b Author: focused_xy <[email protected]> Date: Fri Oct 25 19:03:26 2024 +0800 feat: 完成 week4 note 1. 以 2048 为例回顾 C 基础语法 2. 认识算法 3. 函数与抽象思维 4. 递归 5. 时间复杂度与Big O表示法 commit 950fa7a Author: Zheng WenJing <[email protected]> Date: Wed Oct 23 21:59:37 2024 +0800 根据意见进行修改 (#49) * 基本完成lec4 note 剩余算法与人工智能模块不明确 * 根据意见进行修改 * 修正图片 commit de14d6b Author: Zheng WenJing <[email protected]> Date: Mon Oct 21 19:51:54 2024 +0800 feat: 基本完成lec4 note 剩余算法与人工智能模块不明确 (#45)
- Loading branch information
1 parent
7e9f808
commit e6d097d
Showing
32 changed files
with
1,785 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,265 @@ | ||
#include "2048.h" | ||
#include <assert.h> //for assert | ||
#include <stdbool.h> // for bool | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <termios.h> // for tcsetattr | ||
#include <time.h> // for time | ||
#include <unistd.h> // for STDOUT_FILENO | ||
|
||
int board[BOARD_SIZE][BOARD_SIZE]; | ||
|
||
void run_game(void) { | ||
initialize_board(); | ||
generate_number(); | ||
print_board(); | ||
enum Direction direction; | ||
bool generate_flag = true; | ||
do { | ||
if (generate_flag) { | ||
generate_number(); | ||
} | ||
print_board(); | ||
while ((direction = choose_direction()) == NONE) { | ||
continue; | ||
} | ||
switch (direction) { | ||
case UP: | ||
generate_flag = move_and_merge_up(); | ||
break; | ||
case DOWN: | ||
generate_flag = move_and_merge_down(); | ||
break; | ||
case LEFT: | ||
generate_flag = move_and_merge_left(); | ||
break; | ||
case RIGHT: | ||
generate_flag = move_and_merge_right(); | ||
break; | ||
default: | ||
assert(0); | ||
} | ||
} while (!is_finished()); | ||
} | ||
|
||
bool is_finished(void) { | ||
bool flag_no_space = true; | ||
for (int i = 0; i < BOARD_SIZE; i++) { | ||
for (int j = 0; j < BOARD_SIZE; j++) { | ||
if (board[i][j] == 2048) { | ||
return true; | ||
} | ||
if (board[i][j] == 0) { | ||
flag_no_space = false; | ||
} | ||
} | ||
} | ||
return flag_no_space; | ||
} | ||
|
||
void initialize_board(void) { | ||
srand(time(0)); | ||
for (int i = 0; i < BOARD_SIZE; i++) { | ||
for (int j = 0; j < BOARD_SIZE; j++) { | ||
board[i][j] = 0; | ||
} | ||
} | ||
} | ||
|
||
void generate_number(void) { | ||
int empty_space[BOARD_SIZE * BOARD_SIZE][2]; | ||
int count = 0; | ||
|
||
for (int i = 0; i < BOARD_SIZE; i++) { | ||
for (int j = 0; j < BOARD_SIZE; j++) { | ||
if (board[i][j] == 0) { | ||
empty_space[count][0] = i; | ||
empty_space[count][1] = j; | ||
count++; | ||
} | ||
} | ||
} | ||
|
||
if (count > 0) { | ||
int index = rand() % count; | ||
int x = empty_space[index][0]; | ||
int y = empty_space[index][1]; | ||
board[x][y] = (rand() % 2 + 1) * 2; | ||
} | ||
} | ||
|
||
enum Direction choose_direction(void) { | ||
char dir = getchar(); | ||
switch (dir) { | ||
case 'A': | ||
case 'a': | ||
return LEFT; | ||
case 'W': | ||
case 'w': | ||
return UP; | ||
case 'S': | ||
case 's': | ||
return DOWN; | ||
case 'D': | ||
case 'd': | ||
return RIGHT; | ||
default: | ||
return NONE; | ||
} | ||
} | ||
|
||
void print_board(void) { | ||
system("clear"); | ||
printf("-------------------------\n"); | ||
for (int i = 0; i < BOARD_SIZE; i++) { | ||
putchar('|'); | ||
for (int j = 0; j < BOARD_SIZE; j++) { | ||
if (board[i][j] != 0) { | ||
printf("%5d|", board[i][j]); | ||
} else { | ||
printf(" |"); | ||
} | ||
} | ||
putchar('\n'); | ||
} | ||
printf("-------------------------\n"); | ||
} | ||
|
||
void swap(int *a, int *b) { | ||
int tmp = *a; | ||
*a = *b; | ||
*b = tmp; | ||
} | ||
|
||
bool move_and_merge_left(void) { | ||
bool moved_flag = false; | ||
for (int row = 0; row < BOARD_SIZE; row++) { | ||
for (int col = 0; col < BOARD_SIZE - 1; col++) { | ||
if (board[row][col] == 0) { | ||
for (int search_col = col + 1; search_col < BOARD_SIZE; search_col++) { | ||
if (board[row][search_col] != 0) { | ||
moved_flag = true; | ||
swap(&board[row][col], &board[row][search_col]); | ||
break; | ||
} | ||
} | ||
} | ||
int next_not_zero_col = col + 1; | ||
while (board[row][next_not_zero_col] == 0 && | ||
next_not_zero_col < BOARD_SIZE) | ||
next_not_zero_col++; | ||
if (next_not_zero_col < BOARD_SIZE && | ||
board[row][col] == board[row][next_not_zero_col]) { | ||
moved_flag = true; | ||
board[row][col] *= 2; | ||
board[row][next_not_zero_col] = 0; | ||
} | ||
} | ||
} | ||
return moved_flag; | ||
} | ||
|
||
bool move_and_merge_right(void) { | ||
bool moved_flag = false; | ||
for (int row = 0; row < BOARD_SIZE; row++) { | ||
for (int col = BOARD_SIZE - 1; col > 0; col--) { | ||
if (board[row][col] == 0) { | ||
for (int search_col = col - 1; search_col >= 0; search_col--) { | ||
if (board[row][search_col] != 0) { | ||
moved_flag = true; | ||
swap(&board[row][col], &board[row][search_col]); | ||
break; | ||
} | ||
} | ||
} | ||
int next_not_zero_col = col - 1; | ||
while (board[row][next_not_zero_col] == 0 && next_not_zero_col >= 0) | ||
next_not_zero_col--; | ||
if (next_not_zero_col >= 0 && | ||
board[row][col] == board[row][next_not_zero_col]) { | ||
moved_flag = true; | ||
board[row][col] *= 2; | ||
board[row][next_not_zero_col] = 0; | ||
} | ||
} | ||
} | ||
return moved_flag; | ||
} | ||
|
||
bool move_and_merge_up(void) { | ||
bool moved_flag = false; | ||
for (int col = 0; col < BOARD_SIZE; col++) { | ||
for (int row = 0; row < BOARD_SIZE - 1; row++) { | ||
if (board[row][col] == 0) { | ||
for (int search_row = row + 1; search_row < BOARD_SIZE; search_row++) { | ||
if (board[search_row][col] != 0) { | ||
moved_flag = true; | ||
swap(&board[row][col], &board[search_row][col]); | ||
break; | ||
} | ||
} | ||
} | ||
int next_not_zero_row = row + 1; | ||
while (board[next_not_zero_row][col] == 0 && | ||
next_not_zero_row < BOARD_SIZE) | ||
next_not_zero_row++; | ||
if (next_not_zero_row < BOARD_SIZE && | ||
board[row][col] == board[next_not_zero_row][col]) { | ||
moved_flag = true; | ||
board[row][col] *= 2; | ||
board[next_not_zero_row][col] = 0; | ||
} | ||
} | ||
} | ||
return moved_flag; | ||
} | ||
|
||
bool move_and_merge_down(void) { | ||
bool moved_flag = false; | ||
for (int col = 0; col < BOARD_SIZE; col++) { | ||
for (int row = BOARD_SIZE - 1; row > 0; row--) { | ||
if (board[row][col] == 0) { | ||
for (int search_row = row - 1; search_row >= 0; search_row--) { | ||
if (board[search_row][col] != 0) { | ||
moved_flag = true; | ||
swap(&board[row][col], &board[search_row][col]); | ||
break; | ||
} | ||
} | ||
} | ||
int next_not_zero_row = row - 1; | ||
while (board[next_not_zero_row][col] == 0 && next_not_zero_row >= 0) | ||
next_not_zero_row--; | ||
if (next_not_zero_row >= 0 && | ||
board[row][col] == board[next_not_zero_row][col]) { | ||
moved_flag = true; | ||
board[row][col] *= 2; | ||
board[next_not_zero_row][col] = 0; | ||
} | ||
} | ||
} | ||
return moved_flag; | ||
} | ||
|
||
/* 禁用终端缓存区和回显 */ | ||
void disable_buffering(struct termios *old_attr) { | ||
struct termios new_attr; | ||
tcgetattr(STDIN_FILENO, old_attr); | ||
new_attr = *old_attr; | ||
new_attr.c_lflag &= ~(ICANON | ECHO); | ||
tcsetattr(STDIN_FILENO, TCSANOW, &new_attr); | ||
} | ||
|
||
/* 恢复终端 */ | ||
void restore_buffering(struct termios *old_attr) { | ||
tcsetattr(STDIN_FILENO, TCSANOW, old_attr); | ||
} | ||
|
||
int main(void) { | ||
struct termios old_attr; | ||
disable_buffering(&old_attr); | ||
run_game(); | ||
restore_buffering(&old_attr); | ||
printf("Game End...\n"); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef __2048_H__ | ||
#define __2048_H__ | ||
|
||
#include <stdbool.h> | ||
|
||
#define BOARD_SIZE 4 | ||
extern int board[BOARD_SIZE][BOARD_SIZE]; | ||
enum Direction{UP, DOWN, LEFT, RIGHT, NONE}; | ||
|
||
/* run the game */ | ||
void run_game(void); | ||
/* initialize the board */ | ||
void initialize_board(void); | ||
/* generate randon number at board */ | ||
void generate_number(void); | ||
/* get the direciton from keyboard input */ | ||
enum Direction choose_direction(void); | ||
/* print the game board */ | ||
void print_board(void); | ||
|
||
/* helper function */ | ||
void swap(int *a, int *b); | ||
/* determine if the game is over */ | ||
bool is_finished(void); | ||
/* move left */ | ||
bool move_and_merge_left(void); | ||
/* move right */ | ||
bool move_and_merge_right(void); | ||
/* move up */ | ||
bool move_and_merge_up(void); | ||
/* move down */ | ||
bool move_and_merge_down(void); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
在本目录下打开终端,输入: | ||
|
||
```bash | ||
make | ||
``` | ||
|
||
在`./build`目录下生成对应的可执行文件 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/time.h> | ||
|
||
#define N 10000 | ||
int arr[N]; | ||
|
||
double get_time() { | ||
struct timeval tv; | ||
gettimeofday(&tv, NULL); | ||
return tv.tv_sec + tv.tv_usec / 1000000.0; | ||
} | ||
|
||
void bubble_sort(int *arr, int n) { | ||
int i, j, tmp; | ||
for (i = 0; i < n; i++) { | ||
for (j = n - 1; j > i; j--) { | ||
if (arr[j] < arr[j - 1]) { | ||
tmp = arr[j - 1]; | ||
arr[j - 1] = arr[j]; | ||
arr[j] = tmp; | ||
} | ||
} | ||
} | ||
} | ||
|
||
void merge_sort(int *arr, int l, int r) { | ||
if (l >= r) | ||
return; | ||
int mid = (l + r) / 2; | ||
merge_sort(arr, l, mid); | ||
merge_sort(arr, mid + 1, r); | ||
int *buffer = (int *)malloc(sizeof(int) * (r - l + 1)), len = 0; | ||
int i = l, j = mid + 1; | ||
while (i <= mid && j <= r) { | ||
buffer[len++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; | ||
} | ||
while (i <= mid) { | ||
buffer[len++] = arr[i++]; | ||
} | ||
while (j <= r) { | ||
buffer[len++] = arr[j++]; | ||
} | ||
memcpy(arr + l, buffer, sizeof(int) * len); | ||
free(buffer); // REMEMBER!!! | ||
return; | ||
} | ||
|
||
void init() { | ||
srand(114514); | ||
int i; | ||
for (i = 0; i < N * 4; i++) { | ||
int x = rand() % N, y = rand() % N, tmp; | ||
tmp = arr[x]; | ||
arr[x] = arr[y]; | ||
arr[y] = tmp; | ||
} | ||
return; | ||
} | ||
|
||
int main() { | ||
double start_time = 0, end_time = 0; | ||
init(); | ||
|
||
start_time = get_time(); | ||
merge_sort(arr, 0, N - 1); | ||
end_time = get_time(); | ||
printf("merge_sort cost : %.6lf second on datasize:[%d]\n", | ||
end_time - start_time, N); | ||
|
||
init(); | ||
|
||
start_time = get_time(); | ||
bubble_sort(arr, N); | ||
end_time = get_time(); | ||
printf("bubble_sort cost : %.6lf second on datasize:[%d]\n", | ||
end_time - start_time, N); | ||
return 0; | ||
} |
Oops, something went wrong.