Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
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
E1PsyCongroo committed Oct 26, 2024
1 parent 7e9f808 commit e6d097d
Show file tree
Hide file tree
Showing 32 changed files with 1,785 additions and 0 deletions.
265 changes: 265 additions & 0 deletions Lectures/Lecture4/Codes/2048.c
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;
}
34 changes: 34 additions & 0 deletions Lectures/Lecture4/Codes/2048.h
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
7 changes: 7 additions & 0 deletions Lectures/Lecture4/Codes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
在本目录下打开终端,输入:

```bash
make
```

`./build`目录下生成对应的可执行文件
80 changes: 80 additions & 0 deletions Lectures/Lecture4/Codes/bubble_vs_merge.c
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;
}
Loading

0 comments on commit e6d097d

Please sign in to comment.