Commit 5cea74b4 authored by Paul Nechifor's avatar Paul Nechifor
Browse files

Initial commit.

parents
rapide.idx
rapide.txt
grila.idx
grila.txt
all: clean client server sfarsit linii
client: client.o culori.o interfata.o harta.o protocolp.o
gcc -o client client.o culori.o interfata.o harta.o protocolp.o -lcurses
server: server.o vecini.o protocolp.o intrebare.o
gcc -o server server.o vecini.o protocolp.o intrebare.o -lcurses
client.o:
gcc -c client.c
server.o:
gcc -c server.c
culori.o:
gcc -c culori.c
interfata.o:
gcc -c interfata.c
harta.o:
gcc -c harta.c
protocolp.o:
gcc -c protocolp.c
vecini.o:
gcc -c vecini.c
intrebare.o:
gcc -c intrebare.c
clean:
rm -fr *.o client server iclient_* iserver_* j_*
sfarsit:
rm -fr *.o
linii:
clear
wc -l culori.h interfata.h harta.h protocolp.h intrebare.h vecini.h macro.h culori.c interfata.c harta.c protocolp.c intrebare.c vecini.c client.c server.c Makefile
crrifc
======
This is a multiplayer map-based quiz game (ConQUIZtador clone) written in C for
Linux. I wrote this in my first year before doing network programming so it
doesn't use socket, but rather named pipes. This means it would only work on the
same computer. This was my intent since I wrote it in order to run it on Fenrir
(the students' server of my faculty).
Sadly this repo is missing the data files since I'm not sure I should make them
public, but you can ask me for them.
[Demo on YouTube][1]:
[![demo](http://img.youtube.com/vi/QlaqZcl0R_A/0.jpg)][1]
## The protocol
This is how I documented it back then in Romanian.
### Ce trimite clientul
`CONE +1` - conectare si numele de utilizator (<=12 caractere)
`TRIR +1` - trimit raspunsul pentru intrebarea rapida x
`TRIG +1` - trimit raspunsul pentru intrebarea grila: varianta x
`ALEG +1` - aleg teritoriul x
`ATAC +1` - atac teritoriul x
### Ce trimite serverul
`AIIN +0 s` - ai intrat pe server
`SNTJ +1` - sunt n jucatori
`JUCS +3` - jucatorii sunt x, y, z
`PUNS +3` - punctele sunt x, y, z
`INTR +1` - intrebare rapida: x
`INTG +5` - intrebare grila: x . varianta 1: y varianta 2: z ...
`RASR +4` - raspunsul pentru intrebarea rapida era x. j1 a zis y, j2 ...
`RASG +4` - raspunsul pentru intrebarea grila era varianta x; j1 a zis y ...
`JALG +1` - jucatorul x trebuie sa aleaga un teritoriu
`TBAL >1 s` - trebuie sa alegi un teritoriu dintre x, y, z, ...
`JALT +2` - jucatorul x a ales teritoriul y
`JATC +1` - jucatorul x trebuie sa atace un teritoriu
`TBAT >1 s` - trebuie sa ataci un teritoriu dintre x, y, ...
`JATT +2` - jucatorul x a ales sa atace teritoriul y
[1]: http://www.youtube.com/watch?v=QlaqZcl0R_A
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "culori.h"
#include "harta.h"
#include "interfata.h"
#include "protocolp.h"
#include "macro.h"
int culoriTeritorii[15];
int input, output, conect;
void asteaptaAcceptarea(void);
void dimensiuneTerminal(void);
void reafiseazaHarta(void);
void mainLoop(void);
int main(int argc, char *argv[])
{
int i, ret;
char fis[50];
if (argc < 3)
{
printf("Utilizare: %s NUME JOC\n", argv[0]);
exit(1);
}
initscr();
start_color();
initializeazaCulori();
/* asteapta sa mareasca terminalul inainte de a continua */
dimensiuneTerminal();
/* creaza si deschide canalul de intrare client */
strcpy(fis, "iclient_");
strcat(fis, argv[1]);
ret = mkfifo(fis, 0666);
if (ret == -1 && ret != EEXIST)
DIE("Eroare la crearea canalului de input");
if ( (input = open(fis, O_RDONLY | O_NONBLOCK)) == -1)
DIE("Eroare la deschiderea canalului de input");
/* deschide canalul de conectare server */
if ( (conect = open(argv[2], O_WRONLY)) == -1)
DIE("Nu exista acest joc\n");
/* scrie cererea de conectare */
scrie(2, conect, "CONE", argv[1]);
/* inchide canalul de conectare */
if (close(conect) == -1)
DIE("Nu s-a putut inchide canalul serverului");
/* asteapta sa primiesti mesajul de conectare */
asteaptaAcceptarea();
/* deschide canalul de output */
strcpy(fis, "iserver_");
strcat(fis, argv[1]);
if ( (output = open(fis, O_WRONLY)) == -1)
DIE("Eroare la deschiderea canalului de output");
/* initializeaza teritoriile */
for (i=0; i<15; i++)
culoriTeritorii[i] = COL_NECUCERIT;
creazaInterfata("", "", "");
reafiseazaHarta();
status("Am fost acceptat pe server.");
mesajServer("Incepe jocul.");
/* bucla principala */
mainLoop();
endwin();
return 0;
}
void mainLoop(void)
{
int mesg, rasp, col;
char textul[100];
for (;;)
{
usleep(100000);
mesg = citeste(input);
switch (mesg)
{
case NIMIC:
break;
case S_JUCS:
mesajServer("Numele jucatorilor");
creazaInterfata(campuri[1], campuri[2], campuri[3]);
break;
case S_PUNS:
mesajServer("Actualizarea punctelor");
puncteJucator(1, atoi(campuri[1]));
puncteJucator(2, atoi(campuri[2]));
puncteJucator(3, atoi(campuri[3]));
break;
case S_INTR:
mesajServer("Raspunde la intrebare");
rasp = puneIntrebareRapida(campuri[1]);
sprintf(textul, "%d", rasp);
scrie(2, output, "TRIR", textul);
sprintf(textul, "Am trimis raspunsul '%d' la server.", rasp);
status(textul);
break;
case S_INTG:
break;
case S_RASR:
mesajServer("Rezultatele");
afiseazaRaspunsRapid(atoi(campuri[1]), atoi(campuri[2]), atoi(campuri[3]), atoi(campuri[4]));
reafiseazaHarta();
break;
case S_RASG:
break;
case S_JALG:
sprintf(textul, "Jucatorul %s trebuie sa aleaga un teritoriu", campuri[1]);
mesajServer(textul);
break;
case S_TBAL:
mesajServer("Trebuie sa alegi un teritoriu");
textul[0] = teritoriuDeAles(campuri[1], atoi(campuri[2]));
textul[1] = 0;
reafiseazaHarta();
scrie(2, output, "ALEG", textul);
break;
case S_JALT:
sprintf(textul, "Jucatorul %s are teritoriul '%s'.", campuri[1], campuri[2]);
mesajServer(textul);
rasp = atoi(campuri[1]);
switch (rasp)
{
case 1: col = COL_J1; break;
case 2: col = COL_J2; break;
case 3: col = COL_J3; break;
default: endwin(); printf("Nu exista alt jucator\n"); exit(1);
}
modificaTeritoriu(campuri[2][0], col);
culoriTeritorii[campuri[2][0]-'A'] = col;
break;
case S_JATC:
break;
case S_TBAT:
break;
case S_JATT:
break;
default:
printw("Nu recunosc mesajul '%s'.\n", campuri[0]);
break;
}
}
}
void asteaptaAcceptarea(void)
{
int i, mesg;
for (i=0; i<100; i++)
{
usleep(100000);
mesg = citeste(input);
switch (mesg)
{
case NIMIC:
break;
case S_AIIN:
printw("Ai intrat.\n");
/* intoarce-te cu succes */
return;
default:
printw("Nu recunost mesajul '%s'.\n", campuri[0]);
break;
}
}
/* am primit mesajul de conectare in 10 secunde */
DIE("Nu am primit mesajul de conectare\n");
}
void dimensiuneTerminal(void)
{
int lin, col;
do
{
/* oare de ce nu trebuie sa dau adresele pentru lin si col */
getmaxyx(stdscr, lin, col);
if (lin < MIN_LINES || col < MIN_COLS)
{
move(0, 0);
printw("Trebuie sa ai terminalul de minim %03d linii si %03d coloane.\n"
"Terminalul tau are %03d linii si %03d coloane.\nApasa o tasta dupa"
"ce ai marit fereastra.", MIN_LINES, MIN_COLS, lin, col);
refresh();
getch();
}
}
while (lin < MIN_LINES || col < MIN_COLS);
}
void reafiseazaHarta(void)
{
int i;
afiseazaFundal();
afiseazaGranita();
for (i=0; i<15; i++)
afiseazaTeritoriu((char)i + 'A', culoriTeritorii[i]);
}
#include <curses.h>
#include "culori.h"
void initializeazaCulori(void)
{
init_pair(COL_GRANITA, COLOR_BLACK, COLOR_BLACK);
init_pair(COL_FUNDAL, COLOR_RED, COLOR_WHITE);
init_pair(COL_NECUCERIT, COLOR_BLACK, COLOR_WHITE);
init_pair(COL_J1, COLOR_BLACK, COLOR_BLUE);
init_pair(COL_J2, COLOR_BLACK, COLOR_YELLOW);
init_pair(COL_J3, COLOR_BLACK, COLOR_RED);
init_pair(COL_STATUS, COLOR_GREEN, COLOR_BLACK);
init_pair(COL_MESAJ_SERVER, COLOR_BLACK, COLOR_GREEN);
init_pair(COL_FUNDAL_INTREBARE, COLOR_GREEN, COLOR_BLACK);
init_pair(COL_INTREBARE, COLOR_BLACK, COLOR_GREEN);
init_pair(COL_RASPUNS, COLOR_BLACK, COLOR_YELLOW);
}
#ifndef _CULORI_H
#define _CULORI_H
/* indici de culori */
#define COL_GRANITA 1
#define COL_FUNDAL 2
#define COL_NECUCERIT 3
#define COL_J1 4
#define COL_J2 5
#define COL_J3 6
#define COL_MESAJ_SERVER 7
#define COL_STATUS 8
#define COL_FUNDAL_INTREBARE 9
#define COL_INTREBARE 10
#define COL_RASPUNS 11
void initializeazaCulori(void);
#endif //_CULORI_H
#include <curses.h>
#include "harta.h"
#include "macro.h"
#include "culori.h"
char liniiHarta[42][120] = {
" #### ##### ",
" ###AA##### ####BBB### ",
" ####AAAAAAAA###### #########BBBBBBBB### ",
" #########AAAAAAAAAAAAAAAA##### ###BBBBBBBBBBBBBBBBBB## ",
" ##K##AAAAAAAAAAAAAaAAAAAAAAAAA###BBBBBBBBBbBBBBBBBBBBB#### ",
" ###KK###AAAAAAAAAAAAAAAAAAAAAAAAA##BBBBBBBBBBBBBBBBB#####CC## ",
" ##KKKKKK################AAAAAAAAAA##BBBBBBBBBBBBBBB##CCCCCCCC### ",
" ###KKKKKKKKKKKKKKKKKKKKK##AAAAAAAAA##BBBBBB###########CCCCCcCCCCC#### ",
" ##KKKKKKKKKKKKKKKKKKKKKKKK##AAAAAAA###########CCCCCCCCCCCCCCCCCCCCCCC## ",
" ##KKKKKKKKKKKKKkKKKKKKKKKKKK##AAA####OOOOOOOO##CCCCCCCCCCCCCCCC######CC## ",
" #####KKKKKKKKKKKKKKKKKKKKKKKKK##AA###OOOOOOOOOOOO##CCCCCCC#########DDDD####### ",
" ###JJJ#######KKKKK####KKKKKKKKKK#####OOOOOOOOOOOOOOO#########DDDDDDDDDDDDDDDDDD## ",
" ##JJJJJJJJJJJ####K##LL########KKK#OOOOOOOOOOOOoOOOOOOO##DDDDDDDDDDDDDDDDDDDDDDDD## ",
" ##### ######JJJJJJJJJJJJJJJ###LLLLLLLLLL######OOOOOOOOOOOOOOOOOOOO###DDDDDDDDDDdDDDDDDDDDDD## ",
"##JJJ###JJJJJJJJJJJJJJJJJJ###LLLLLLLLLLLLLLLLL#######OOOOOOOOOOOOOOOO##DDDDDDDDDDDDDDDDDDDDD## ",
" ##JJJJJJJJJJJJJJJJJJJJJJ##LLLLLLLLLLLLLLLLLLLLLLLL###########OOOOOOOOO##DDDDD################ ",
" ##JJJJJJJJJJJJJJJJJJJ##LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL##OOOOOOOOO#######EEEEEEEEEEEEE## ",
" ##JJJJJJJJJjJJJJJJJJJ##LLLLLLLLLLlLLLLLLLLLLLLLLLLLLLLLLLL##OOOOOOO##EEEEEEEEEEEeEEEEEEEE## ",
" ##JJJJJJJJJJJJJJJJJJJJ##LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL####OO####EEEEEEEEEEEEEEEEEEEE## ",
" ##JJJJJJJJJJJJJJJJJJJJJ##LLLLLLLLLLLLLLL###############LLLLLLLLLL###NN#####EEEEEEEEEEEEEEEE## ",
" ##JJJJJJJJJJJJJJJJJJJJJ##LLLLLLLLLL#####MMMMMMMMMMMMM##LL##########NNNNNN######EE#####EEEE#### ######## ",
" ####JJJJJJJJJJJJJJJJJ##############I##MMMMMMMMMMMMMMM####MMMMMMMM##NNNNNNNNNN####NNN######FF### ####FFFFFFF## ",
" ####JJJJJJJJJJJJJJ##IIIIIIIIIIIII##MMMMMMMMMMMMMMMMMMMMMMMMMMM####NNNNNNNNNNNNNNNNNN##FFFFF####FFFFFFFFFFF## ",
" ##JJJJJJJJJJJJJJ##IIIIIIIIIIIII###MMMMMMMMMMMMMmMMMMMMMMMMMMMMMM##NNNNNNNNNNNNNNNNNNN##FFFFFFFFFFFFFFFFFFF##",
" ##JJJJJJJJJJJJ###IIIIIIIIIIIII##MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM##NNNNNNNnNNNNNNNNNNN##FFFFFFFFFFFFFFFFFF# ",
" ##JJJJJJJJJJJ##IIIIIIIIIIIIIIII##MMMMM####MMMMMMMMMMMMMMMMMMMMMMMMM###NNNNNNNNNNNNNNNNN##FFFFFFFFFF##FFFF### ",
" ###JJJJJJ#####IIIIIIIIIIIIIIII##MMMM##II##MMMMMMMMMMMMMMMMMMM#####GG####################FFFFFFFFF######## ",
" ######## ###IIIIIIIIIIIIIII#MMMM##IIII##MMMMMMMMMMMMMM###HH##GGGGGGGGGGGGGGGGGGGG##FFFFFFFFF## ",
" ####IIIIIIIiIIIIIII######IIIII##MMMMMM#########HHHHH##GGGGGGGGGGGGGGGGGGGG##FFFFfFFFF# ",
" #IIIIIIIIIIIIIIIIIIIIIIIIIIIII#########HHHHHHHHHHHHHH##GGGGGGGGgGGGGGGGGGGG#FFFFFFFFF## ",
" ##IIIIIIIIIIIIIIIIIIIIIIIIIIIIII##HHHHHHHHHHHHHHHHHHH##GGGGGGGGGGGGGGGGGGG##FFFFFFFF## ",
" ##IIIIIIIIIIIIIIIIIIIIIIIIIIII##HHHHHHHHHHHHHHHHHHH##GGGGGGGGGGGGGGGGG####FFFFFFFFF## ",
" ###IIIIIIIIIIIIIIIIIIIIIIIIII##HHHHHHHHHHHHHHHHHHHH##GGGGGGGGGGGGG###FFFFFFFFFFFFFF## ",
" ###IIIIIIIIIIIIIIIIIIIIII###HHHHHHHHHhHHHHHHHHHHH###GGG##########FFFFFFFFFFFFFFFF## ",
" ##IIIIIIIIIIIIIIIIIIIIII##HHHHHHHHHHHHHHHHHHHH########## #########FFFFFFFFF## ",
" ########IIIIIIIIIIIIIII##HHHHHHHHHHHHHHHHHH### ##FFFFFFFF## ",
" #######IIIIIIIIII##HHHHHHHHHHHHHHHH## ######FFF## ",
" ##################HHHHHHHHH### ##### ",
" ########### "
};
void afiseazaGranita(void)
{
int i, j, muta;
attrset(COLOR_PAIR(COL_GRANITA));
for (i=0; i<HLIN; i++)
{
muta = 1;
for (j=0; j<HCOL; j++)
if (liniiHarta[i][j] == '#')
{
if (muta) move(i+START_LIN, j+START_COL);
addch(' ');
muta = 0;
}
else muta = 1;
}
CAPAT();
refresh();
}
void afiseazaFundal(void)
{
int i, j;
///bkgd(COLOR_PAIR(COL_FUNDAL));
attrset(COLOR_PAIR(COL_FUNDAL));
for (i=1; i<MIN_LINES-2; i++)
{
move(i, 0);
for (j=0; j<MIN_COLS; j++)
addch(' ');
}
CAPAT();
refresh();
}
void afiseazaTeritoriu(char t, int culoare)
{
int i, j, muta;
attrset(COLOR_PAIR(culoare));
for (i=0; i<HLIN; i++)
{
muta = 1;
for (j=0; j<HCOL; j++)
if (toupper(liniiHarta[i][j]) == t)
{
if (muta) move(i+START_LIN, j+START_COL);
if (!(liniiHarta[i][j] & 32)) addch(' ');
else addch(t);
muta = 0;
}
else muta = 1;
}
CAPAT();
refresh();
}
void modificaTeritoriu(char t, int culoare)
{
int i, j, muta, aFost;
attrset(COLOR_PAIR(culoare));
for (i=0; i<HLIN; i++)
{
aFost = 0;
muta = 1;
for (j=0; j<HCOL; j++)
if (toupper(liniiHarta[i][j]) == t)
{
if (muta) move(i+START_LIN, j+START_COL);
if (!(liniiHarta[i][j] & 32)) addch(' ');
else addch(t);
muta = 0;
aFost = 1;
}
else muta = 1;
if (aFost)
{
CAPAT();
refresh();
napms(60);
}
}
CAPAT();
refresh();
}
#ifndef _HARTA_H
#define _HARTA_H
/* de unde incepe afisearea partilor hartii */
#define START_LIN 2
#define START_COL 0
/* cat de mare este harta */
#define HLIN 41
#define HCOL 117
void afiseazaGranita(void);
void afiseazaFundal(void);
void afiseazaTeritoriu(char t, int culoare);
void modificaTeritoriu(char t, int culoare);
#endif //_HARTA_H
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, d, n, in, out, lin=1, poz=0, afost=1;
char buf[1024];
in = open("grila.txt", O_RDONLY);
out = creat("grila.idx", 0644);
while ( (n=read(in, buf, 1024)) > 0)
{
for (i=0; i<n; i++)
{
if (lin % 6 == 1 && afost)
{
write(out, &poz, 4);
printf("chr = '%c' lin=%d poz=%d \n", buf[i], lin, poz);
}
if (buf[i] == '\n')
{
lin++;
afost = 1;
}
else afost = 0;
poz++;
}
}
close(in);
close(out);
return 0;
}
#include <curses.h>
#include <string.h>
#include <ctype.h>
#include "interfata.h"
#include "culori.h"
#include "macro.h"
void creazaInterfata(char* j1, char* j2, char* j3)
{
int i, pe = (LUNGIME - 3 * 25) / 6;
move(START_PUNCTE, 0);
attrset(COLOR_PAIR(COL_J1));
for (i=0; i<pe; i++) addch(' ');
printw("J1: %-12s P: %04d", j1, 0);
for (i=0; i<pe; i++) addch(' ');
attrset(COLOR_PAIR(COL_J2));
for (i=0; i<pe; i++) addch(' ');
printw("J2: %-12s P: %04d", j2, 0);
for (i=0; i<pe; i++) addch(' ');
attrset(COLOR_PAIR(COL_J3));
for (i=0; i<pe; i++) addch(' ');
printw("J3: %-12s P: %04d", j3, 0);
for (i=0; i<pe; i++) addch(' ');
CAPAT();
refresh();
}
void puncteJucator(int nr, int puncte)
{
/* (2*nr-1)pe + nr*25 - 4 */
switch (nr)
{
case 1: attrset(COLOR_PAIR(COL_J1)); break;
case 2: attrset(COLOR_PAIR(COL_J2)); break;
case 3: attrset(COLOR_PAIR(COL_J3)); break;
}
move(START_PUNCTE, (2*nr-1)*((LUNGIME - 3*25)/6) + nr*25 - 4 );
printw("%04d", puncte);
CAPAT();
refresh();
}
void status(char* mesaj)
{
char *m = "Status: ";
int i, rest = LUNGIME - strlen(m) - strlen(mesaj);
move(START_MESAJE, 0);
attrset(COLOR_PAIR(COL_STATUS));
printw("%s%s", m, mesaj);
for (i=0; i<rest; i++) addch(' ');
CAPAT();
refresh();
}
void mesajServer(char* mesaj)
{
char *m = "Mesaj server: ";
int i, rest = LUNGIME - strlen(m) - strlen(mesaj);
move(START_MESAJE + 1, 0);
attrset(COLOR_PAIR(COL_MESAJ_SERVER));
printw("%s%s", m, mesaj);
for (i=0; i<rest; i++) addch(' ');
CAPAT();
refresh();