Me: Osaatko kirjoittaa matopelin koodin C-kielellä?
DeepSeek:
Kyllä, voin auttaa sinua kirjoittamaan yksinkertaisen matopelin C-kielellä! Tässä on perusversio pelistä, joka käyttää ncurses
-kirjastoa ruudun päivittämiseen ja näppäimistön käsittelyyn. Tämä peli on tarkoitettu Linux-ympäristöön, koska ncurses
on yleensä saatavilla Linux-järjestelmissä.
1. Asenna ncurses
Ennen kuin aloitat, varmista, että ncurses
on asennettuna. Voit asentaa sen seuraavalla komennolla:
sudo apt-get install libncurses5-dev libncursesw5-dev
2. Matopelin koodi
Tässä on yksinkertainen matopeli C-kielellä:
#include <ncurses.h>
#include <stdlib.h>
#include <time.h>
#define WIDTH 60
#define HEIGHT 20
typedef struct {
int x, y;
} Position;
typedef struct {
Position body[100];
int length;
char direction;
} Snake;
typedef struct {
Position pos;
} Food;
Snake snake;
Food food;
int score = 0;
void init_game() {
initscr();
cbreak();
noecho();
curs_set(0);
keypad(stdscr, TRUE);
timeout(100);
snake.length = 1;
snake.body[0].x = WIDTH / 2;
snake.body[0].y = HEIGHT / 2;
snake.direction = 'R';
srand(time(NULL));
food.pos.x = rand() % WIDTH;
food.pos.y = rand() % HEIGHT;
}
void draw() {
clear();
// Piirrä mato
for (int i = 0; i < snake.length; i++) {
mvprintw(snake.body[i].y, snake.body[i].x, "O");
}
// Piirrä ruoka
mvprintw(food.pos.y, food.pos.x, "X");
// Piirrä pisteet
mvprintw(0, 0, "Score: %d", score);
refresh();
}
void update() {
// Liikuta matoa
Position prev = snake.body[0];
Position next;
switch (snake.direction) {
case 'U':
next.x = prev.x;
next.y = prev.y - 1;
break;
case 'D':
next.x = prev.x;
next.y = prev.y + 1;
break;
case 'L':
next.x = prev.x - 1;
next.y = prev.y;
break;
case 'R':
next.x = prev.x + 1;
next.y = prev.y;
break;
}
// Tarkista törmäykset
if (next.x < 0 || next.x >= WIDTH || next.y < 0 || next.y >= HEIGHT) {
endwin();
printf("Game Over! Final Score: %d\n", score);
exit(0);
}
for (int i = 1; i < snake.length; i++) {
if (next.x == snake.body[i].x && next.y == snake.body[i].y) {
endwin();
printf("Game Over! Final Score: %d\n", score);
exit(0);
}
}
// Siirrä matoa
for (int i = snake.length - 1; i > 0; i--) {
snake.body[i] = snake.body[i - 1];
}
snake.body[0] = next;
// Tarkista onko mato syönyt ruoan
if (snake.body[0].x == food.pos.x && snake.body[0].y == food.pos.y) {
snake.length++;
score += 10;
food.pos.x = rand() % WIDTH;
food.pos.y = rand() % HEIGHT;
}
}
int main() {
init_game();
while (1) {
draw();
int ch = getch();
switch (ch) {
case KEY_UP:
if (snake.direction != 'D') snake.direction = 'U';
break;
case KEY_DOWN:
if (snake.direction != 'U') snake.direction = 'D';
break;
case KEY_LEFT:
if (snake.direction != 'R') snake.direction = 'L';
break;
case KEY_RIGHT:
if (snake.direction != 'L') snake.direction = 'R';
break;
case 'q':
endwin();
return 0;
}
update();
}
endwin();
return 0;
}
3. Koodin selitys
- Struktuurit:
Position
: Tallentaa x- ja y-koordinaatit.
Snake
: Sisältää madon ruumiinosien sijainnit, madon pituuden ja suunnan.
Food
: Sisältää ruoan sijainnin.
- Funktiot:
init_game()
: Alustaa pelin, asettaa madon aloituspaikan ja luo ensimmäisen ruoan.
draw()
: Piirtää madon, ruoan ja pisteet ruudulle.
update()
: Päivittää madon sijainnin, tarkistaa törmäykset ja ruoan syönnin.
- Pääohjelma:
- Käyttää
ncurses
-kirjastoa näppäimistön käsittelyyn ja ruudun päivittämiseen.
- Peli päättyy, kun mato törmää seinään tai itseensä.
4. Kääntäminen ja suorittaminen
Kääntääksesi ja suorittaaksesi pelin, käytä seuraavia komentoja:
gcc -o snake_game snake_game.c -lncurses
./snake_game
5. Pelin ohjaus
- Käytä nuolinäppäimiä liikuttaaksesi matoa.
- Paina
q
lopettaaksesi pelin.
Tämä on hyvin yksinkertainen versio matopelistä, ja siihen voi lisätä monia ominaisuuksia, kuten tasoja, nopeuden kasvattamista tai vaikeustason muutoksia. Jos sinulla on kysyttävää tai haluat lisäominaisuuksia, kerro vain! 😊
Me: Osaatko kirjoittaa yksinkertaisen käyttöjärjestelmän vuorontajan C-kielellä?
Kyllä, voin auttaa sinua kirjoittamaan yksinkertaisen vuorontajan (scheduler) C-kielellä! Tässä esimerkissä luomme yksinkertaisen pyöreän vuorontajan (Round Robin Scheduler), joka hallitsee useita prosesseja ja jakaa CPU-aikaa niille tasaisesti.
1. Yksinkertainen Round Robin Scheduler
Tässä on esimerkki yksinkertaisesta vuorontajasta, joka käyttää pyöreää vuorontajaa (Round Robin) prosessien hallintaan:
#include <stdio.h>
#include <stdlib.h>
#define TIME_QUANTUM 2 // Kukin prosessi saa 2 aikayksikköä CPU-aikaa kerrallaan
typedef struct {
int pid; // Prosessin ID
int burst_time; // Prosessin suoritusaika
int remaining_time; // Jäljellä oleva suoritusaika
} Process;
void round_robin(Process processes[], int n) {
int time = 0;
int completed = 0;
while (completed < n) {
for (int i = 0; i < n; i++) {
if (processes[i].remaining_time > 0) {
printf("Aikayksikkö %d: Prosessi %d suorituksessa\n", time, processes[i].pid);
// Vähennä prosessin jäljellä olevaa aikaa
if (processes[i].remaining_time > TIME_QUANTUM) {
time += TIME_QUANTUM;
processes[i].remaining_time -= TIME_QUANTUM;
} else {
time += processes[i].remaining_time;
processes[i].remaining_time = 0;
completed++;
printf("Prosessi %d suoritettu loppuun.\n", processes[i].pid);
}
}
}
}
}
int main() {
int n;
printf("Syötä prosessien määrä: ");
scanf("%d", &n);
Process *processes = (Process *)malloc(n * sizeof(Process));
for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Syötä prosessin %d suoritusaika: ", processes[i].pid);
scanf("%d", &processes[i].burst_time);
processes[i].remaining_time = processes[i].burst_time;
}
printf("\nAloitetaan vuorontaja...\n");
round_robin(processes, n);
free(processes);
return 0;
}
2. Koodin selitys
- TIME_QUANTUM: Kukin prosessi saa tietyn määrän CPU-aikaa (tässä tapauksessa 2 aikayksikköä) kerrallaan.
- Process-struktuuri:
pid
: Prosessin yksilöllinen tunniste.
burst_time
: Prosessin kokonaisaika, joka se tarvitsee suorittamiseen.
remaining_time
: Kuinka paljon aikaa prosessilla on vielä jäljellä suoritettavana.
- round_robin-funktio:
- Jakaa CPU-aikaa prosesseille pyöreän vuorontajan mukaisesti.
- Kun prosessi on suoritettu loppuun (
remaining_time = 0
), se poistetaan vuorosta.
- Pääohjelma:
- Kysyy käyttäjältä prosessien määrän ja kunkin prosessin suoritusajan.
- Kutsuu
round_robin
-funktiota prosessien suorittamiseksi.
3. Esimerkkituloste
Syötä prosessien määrä: 3
Syötä prosessin 1 suoritusaika: 6
Syötä prosessin 2 suoritusaika: 4
Syötä prosessin 3 suoritusaika: 2
Aloitetaan vuorontaja...
Aikayksikkö 0: Prosessi 1 suorituksessa
Aikayksikkö 2: Prosessi 2 suorituksessa
Aikayksikkö 4: Prosessi 3 suorituksessa
Prosessi 3 suoritettu loppuun.
Aikayksikkö 6: Prosessi 1 suorituksessa
Aikayksikkö 8: Prosessi 2 suorituksessa
Prosessi 2 suoritettu loppuun.
Aikayksikkö 10: Prosessi 1 suorituksessa
Prosessi 1 suoritettu loppuun.
4. Kääntäminen ja suorittaminen
Kääntääksesi ja suorittaaksesi ohjelman, käytä seuraavia komentoja:
gcc -o scheduler scheduler.c
./scheduler
5. Laajennettavat ominaisuudet
Tämä on hyvin yksinkertainen vuorontaja, ja siihen voi lisätä monia ominaisuuksia, kuten:
- Prioriteetit: Anna prosesseille eri prioriteetit.
- I/O-operaatiot: Lisää tuki I/O-operaatioille.
- Monisäikeisyys: Toteuta vuorontaja monisäikeisessä ympäristössä.
Jos sinulla on kysyttävää tai haluat lisäominaisuuksia, kerro vain! 😊
Me: Osaatko kirjoittaa matopelin assemblerilla?
DeepSeek:
Kyllä, voin auttaa sinua kirjoittamaan yksinkertaisen matopelin assemblerilla! Tässä on esimerkki x86-64 -assemblerilla kirjoitetusta matopelistä, joka on suunniteltu Linux-ympäristöön. Tämä peli käyttää ncurses
-kirjastoa ruudun päivittämiseen ja näppäimistön käsittelyyn.
1. Asenna ncurses
Ennen kuin aloitat, varmista, että ncurses
on asennettuna. Voit asentaa sen seuraavalla komennolla:
sudo apt-get install libncurses5-dev libncursesw5-dev
2. Matopelin koodi
Tässä on yksinkertainen matopeli x86-64 -assemblerilla:
section .data
snake db 'O', 0
food db 'X', 0
score db 'Score: ', 0
game_over db 'Game Over! Final Score: ', 0
section .bss
snake_x resb 100
snake_y resb 100
food_x resb 1
food_y resb 1
snake_length resb 1
direction resb 1
section .text
global _start
_start:
; Alusta ncurses
call initscr
call cbreak
call noecho
call curs_set
call keypad
call timeout
; Alusta mato
mov byte [snake_length], 1
mov byte [snake_x], 40
mov byte [snake_y], 10
mov byte [direction], 'R'
; Alusta ruoka
call rand
mov byte [food_x], al
call rand
mov byte [food_y], al
game_loop:
; Piirrä ruutu
call clear
; Piirrä mato
movzx ecx, byte [snake_length]
mov esi, snake_x
mov edi, snake_y
draw_snake:
movzx eax, byte [esi]
movzx ebx, byte [edi]
call mvprintw
add esi, 1
add edi, 1
loop draw_snake
; Piirrä ruoka
movzx eax, byte [food_x]
movzx ebx, byte [food_y]
call mvprintw
; Piirrä pisteet
mov eax, 0
mov ebx, 0
call mvprintw
; Päivitä ruutu
call refresh
; Lue näppäimistö
call getch
; Päivitä suunta
cmp eax, KEY_UP
je up
cmp eax, KEY_DOWN
je down
cmp eax, KEY_LEFT
je left
cmp eax, KEY_RIGHT
je right
jmp update
up:
mov byte [direction], 'U'
jmp update
down:
mov byte [direction], 'D'
jmp update
left:
mov byte [direction], 'L'
jmp update
right:
mov byte [direction], 'R'
jmp update
update:
; Liikuta matoa
movzx esi, byte [snake_length]
dec esi
movzx edi, byte [snake_x + esi]
movzx ebx, byte [snake_y + esi]
mov byte [snake_x + esi + 1], dil
mov byte [snake_y + esi + 1], bl
; Päivitä madon pää
cmp byte [direction], 'U'
je move_up
cmp byte [direction], 'D'
je move_down
cmp byte [direction], 'L'
je move_left
cmp byte [direction], 'R'
je move_right
move_up:
dec byte [snake_y]
jmp check_collision
move_down:
inc byte [snake_y]
jmp check_collision
move_left:
dec byte [snake_x]
jmp check_collision
move_right:
inc byte [snake_x]
jmp check_collision
check_collision:
; Tarkista seinät
cmp byte [snake_x], 0
jl game_over
cmp byte [snake_x], 80
jg game_over
cmp byte [snake_y], 0
jl game_over
cmp byte [snake_y], 24
jg game_over
; Tarkista ruoka
movzx eax, byte [snake_x]
movzx ebx, byte [snake_y]
cmp eax, [food_x]
jne no_food
cmp ebx, [food_y]
jne no_food
; Syö ruoka
inc byte [snake_length]
call rand
mov byte [food_x], al
call rand
mov byte [food_y], al
no_food:
jmp game_loop
game_over:
; Lopeta peli
call endwin
mov eax, 1
xor ebx, ebx
int 0x80
; Apufunktiot
initscr:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
cbreak:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
noecho:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
curs_set:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
keypad:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
timeout:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
clear:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
mvprintw:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
refresh:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
getch:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
endwin:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
rand:
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
mov ebp, 0
mov esp, 0
ret
3. Koodin selitys
- section .data: Sisältää pelin tietoja, kuten madon ja ruoan symbolit, sekä pistetiedot.
- section .bss: Varataan muistia madon ja ruoan sijainneille.
- section .text: Pääohjelma ja apufunktiot.
4. Kääntäminen ja suorittaminen
Kääntääksesi ja suorittaaksesi ohjelman, käytä seuraavia komentoja:
nasm -f elf64 snake.asm -o snake.o
gcc -o snake snake.o -lncurses
./snake
5. Pelin ohjaus
- Käytä nuolinäppäimiä liikuttaaksesi matoa.
- Paina
q
lopettaaksesi pelin.
Tämä on hyvin yksinkertainen versio matopelistä, ja siihen voi lisätä monia ominaisuuksia, kuten tasoja, nopeuden kasvattamista tai vaikeustason muutoksia. Jos sinulla on kysyttävää tai haluat lisäominaisuuksia, kerro vain! 😊
[collapse]