From 79e6bb683d0ff949bd0a3b832143465dda63459c Mon Sep 17 00:00:00 2001 From: knolax <1339802534.kk@gmail.com> Date: Wed, 15 Mar 2017 12:00:54 -0400 Subject: battleship --- Terminus.ttf | Bin 0 -> 423992 bytes img/hit.bmp | Bin 0 -> 1000138 bytes img/hit.xcf | Bin 0 -> 184580 bytes img/miss.bmp | Bin 0 -> 1000138 bytes img/miss.xcf | Bin 0 -> 210103 bytes img/ship.bmp | Bin 0 -> 2000138 bytes img/ship.xcf | Bin 0 -> 50438 bytes main | Bin 0 -> 74672 bytes main.cpp | 712 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.h | 20 ++ main.o | Bin 0 -> 55720 bytes makefile | 6 + saveo | Bin 0 -> 100 bytes savep | Bin 0 -> 100 bytes so | Bin 0 -> 21 bytes 15 files changed, 738 insertions(+) create mode 100644 Terminus.ttf create mode 100644 img/hit.bmp create mode 100644 img/hit.xcf create mode 100644 img/miss.bmp create mode 100644 img/miss.xcf create mode 100644 img/ship.bmp create mode 100644 img/ship.xcf create mode 100755 main create mode 100644 main.cpp create mode 100644 main.h create mode 100644 main.o create mode 100644 makefile create mode 100644 saveo create mode 100644 savep create mode 100644 so diff --git a/Terminus.ttf b/Terminus.ttf new file mode 100644 index 0000000..3eb75d2 Binary files /dev/null and b/Terminus.ttf differ diff --git a/img/hit.bmp b/img/hit.bmp new file mode 100644 index 0000000..8a999f0 Binary files /dev/null and b/img/hit.bmp differ diff --git a/img/hit.xcf b/img/hit.xcf new file mode 100644 index 0000000..3b9954d Binary files /dev/null and b/img/hit.xcf differ diff --git a/img/miss.bmp b/img/miss.bmp new file mode 100644 index 0000000..d3f6335 Binary files /dev/null and b/img/miss.bmp differ diff --git a/img/miss.xcf b/img/miss.xcf new file mode 100644 index 0000000..3192e56 Binary files /dev/null and b/img/miss.xcf differ diff --git a/img/ship.bmp b/img/ship.bmp new file mode 100644 index 0000000..1ec33f7 Binary files /dev/null and b/img/ship.bmp differ diff --git a/img/ship.xcf b/img/ship.xcf new file mode 100644 index 0000000..314d5f3 Binary files /dev/null and b/img/ship.xcf differ diff --git a/main b/main new file mode 100755 index 0000000..88a4c50 Binary files /dev/null and b/main differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..b62908d --- /dev/null +++ b/main.cpp @@ -0,0 +1,712 @@ +#include +#include +#include +#include +#include +#include +#include "gfx.h" +#include "main.h" +#include "gui.h" +int loop; +float sum; +butt butts; +tbuff texts; +std::string output; +//0 is nothing, 1 is hit, 2 is miss +//orientation +//0 : > +//1 : /\ +//2 : < +// 3 : V +//mask 11000000 +//which ship mask : 00000111 +//hit or miss 00010000 +// whether it is anchor 00100000 +char pfield [10][10]; +char ofield [10][10]; +//game state checking +int ship; // ship currently placed, +int dir; +int game = 0;// determines whether it is the game or not; +//boat placing time : 0 +//player finsihed placing but computer not placed : 2 +//game 1: + +//player won :-1 +//opponent won : -2 +bool turn;// which player's turn +//texture pointers +SDL_Texture * hittp; +SDL_Texture * misstp; +SDL_Texture * shiptp; +SDL_Color red; +SDL_Color white; +int aihits = 0; +int main (int argc, char * argv[]) { + //inits program + initgfx(600,800, "SDL battleship"); + //main loop, this is defined in main.h and global + loop = 1; + hittp = loadtexture("img/hit.bmp"); + misstp = loadtexture("img/miss.bmp"); + shiptp = loadtexture("img/ship.bmp"); + //white color preset + white.r = 255; + white.g = 255; + white.b = 255; + white.a = 255; + //red color preset + red.r = 255; + red.g = 0; + red.b = 0; + red.a = 255; + //adds the gui elements + int si = 0; + int sj = 0; + srandom(time(NULL)); + while (si < 10) { + sj = 0; + while (sj < 10) { + // the fields occupy the left 400px, so 40 per thing, 30 buttons + butts.add(10 + 30 * si,10 + 30 * sj,20,20, "[]"); + pfield[si][sj] = 0; + ofield[si][sj] = 0; + sj++; + } + si++; + } + si = 0; + sj = 0; + while (si < 10) { + sj = 0; + while (sj < 10) { + // the fields occupy the left 400px, so 40 per thing, 30 buttons + butts.add(10 + 30 * si,500 + 30 * sj,20,20, "[]"); + sj++; + } + si++; + } + butts.add(580,0,20,20, "x"); + butts.add(310,700,90,40, "rotate:L"); + butts.add(500,700,90,40, "rotate:R"); + butts.add(400,500,110,20, "bts:4"); + butts.add(400,540,80,20, "sub:3"); + butts.add(400,580,80,20, "des:3"); + butts.add(400,620,50,20, "pat:2"); + butts.add(400,660,140,20, "car:5"); + butts.add(560,30,100,20,"save"); // 208 + //loads the game; + if (argc >= 2) { + int rlx = 0; + int rly = 0; + while (rlx < 10) { + rly = 0; + while (rly < 10) { + ofield[rlx][rly] = (readfile(((std::string)argv[1] + (std::string)"o").c_str()).c_str())[rly + 10 * rlx]; + pfield[rlx][rly] = (readfile(((std::string)argv[1] + (std::string)"p").c_str()).c_str())[rly + 10 * rlx]; + rly++; + } + rlx++; + } + } + while(loop) { + //polls events, which are in a buffer + //returns 1 if there is event in buffer + //returns 0 if buffer is empty + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + //loop is a global defined in main.h + case SDL_QUIT: + //printf("loop = 0;\n"); + loop = 0; + break; + //adds to the text input manager + case SDL_TEXTINPUT: + //if the input buffer was empty before, + //make it the text, which is char[] which + //is *char + texts.charin( event.text.text); + //printf("text input event\n"); + break; + //this only applies if you're typing in chinese + case SDL_TEXTEDITING: + //printf("text editing event\n"); + break; + //for when the moose moves + case SDL_MOUSEMOTION: + butts.hover(event.motion.x, event.motion.y); + texts.hover(event.motion.x, event.motion.y); + break; + //left click only, double clicks cancer out so only odd + case SDL_MOUSEBUTTONDOWN: + if(( event.button.button == SDL_BUTTON_LEFT) && ((event.button.clicks % 2) != 0)) { + if (butts.press(event.button.x, event.button.y) != -1) { + } else { + ship = 0; + int i = 1; + while (i <= 5) { + butts.unpress(i + 200 + 3 + -1); + i++; + } + } + texts.press(event.button.x, event.button.y); + } + break; + } + } + cleargfx(); + //draws all buttons + butts.drawbutt(); + //draws text buffer + texts.drawtbuff(); + checkfieldbutts(true); // this draws hover shadow + checkfieldbutts(false); + checkships(true); // this draws ship lost xs + checkships(false); + checkshipbutts(); // this draws nothing + AI(); + if (butts.state(200) & TOGGLE) { + loop = false; + } + if (butts.state(208) & TOGGLE) { + butts.unpress(208); + writefile("savep",pfield); + writefile("saveo",ofield); + } + checkrotbutts(); + + drawfield(true); // this draws ships and pegs + drawfield(false); + //updates frame + //since only error is an exception + //all the work is done here + drawrect(400,10,110,20, 120,120,120,255); + drawtext(400,10,"bts:4",white); + drawrect(400,50,80,20, 120,120,120,255); + drawtext(400,50,"sub:3",white); + drawrect(400,90,80,20, 120,120,120,255); + drawtext(400,90,"des:3",white); + drawrect(400,130,50,20, 120,120,120,255); + drawtext(400,130,"pat:2",white); + drawrect(400,170,140,20, 120,120,120,255); + drawtext(400,170,"car:5",white); + + drawtext(200,375,"/---=[OPPONENT]=---\\",red); + + drawtext(200,405,"\\---=[ PLAYER ]=---/",red); + if ((game == 0) || (game == 2)) { + drawtext(200,391,"<--------VS-------->",red); + } + if (game == 1) { + if (turn) { + drawtext(200,391,"<---PLAYER TURN---->",red); + } else { + drawtext(200,391,"<-----AI TURN------>",red); + } + } + if (game == -1) { + drawtext(200,391,"<----PLAYER WON---->",red); + } + if (game == -2) { + drawtext(200,391,"<---PLAYER LOST---->",red); + } + //drawgrid(0,0,1,1,true,hittp); + //drawgrid(4,5,1,3,true,shiptp); + //drawgrid(0,5,1,1,false,misstp); + updategfx(); + } + SDL_DestroyTexture(hittp); + SDL_DestroyTexture(misstp); + SDL_DestroyTexture(shiptp); + quitgfx(); + return 0; +} +int getlen(int ship) { + switch(ship) { + default: + return 0; + break; + case 1: + return 4; + break; + case 2: + return 3; + break; + case 3: + return 3; + break; + case 4: + return 2; + break; + case 5: + return 5; + break; + } +} +void checkshipbutts () { + int i = 1; + int offset = -1 + 200 + 3; + while (i <= 5) { + if (butts.state(offset + i) & TOGGLE) { + butts.unpress(offset + i); + eraseship(i); + ship = i; + + } + i++; + } +} + +void drawgrid(int x, int y,int w,int h, bool player, SDL_Texture * t) { + if (player) { + x = x * 30 + 10; + y = y * 30 + 500; + } else { + x = x * 30 + 10; + y = y * 30 + 10; + } + w = w * 20 + (w- 1) * 10; + h = h * 20 + (h- 1) * 10; + drawimg(x, y, w, h, t); +} +// no sanity checking here. +void drawfield(bool player) { + int i = 0; + int j = 0; + if (player) { + i = 0 ; + j = 0; + while (i < 10) { + j = 0; + while ( j < 10) { + char peg; + peg = pfield[i][j]; + if ((peg & 0b00100000) != 0) { + drawship (i,j, peg); + } + j++; + } + i++; + } + } + i = 0; + j = 0; + if (player) { + aihits = 0; + } + while (i < 10) { + j = 0; + while ( j < 10) { + char peg; + if (player) { + peg = pfield[i][j]; + + } else { + peg = ofield[i][j]; + } + if (peg & 0b00010000) { + if ((peg & 0b0000111 )!= 0) { + drawgrid(i, j, 1, 1,player, hittp); + if (player) { + aihits++; + } + //printf("AIHIT%d\n",aihits); + } else { + drawgrid(i, j, 1, 1,player, misstp); + } + } + + j++; + } + i++; + } +} +void checkfieldbutts(bool player) { + int i = 0; + int j = 0; + while (i < 10) { + j = 0; + while (j < 10) { + if (player ) { + if (game == 1) { + } else if (game == 0) { + if (ship != 0) { + if (butts.state(i * 10 + j + 100) & TOGGLE) { + placeship(i,j,ship,dir,true); + ship = 0; + } + if (butts.state(100 + i * 10 + j) & HOVER) { + switch(dir) { + case 0: + drawgrid(i,j,getlen(ship),1,true,shiptp); + break; + case 1: + drawgrid(i,j - getlen(ship) + 1,1,getlen(ship),true,shiptp); + break; + case 2: + drawgrid(i - getlen(ship) + 1,j,getlen(ship),1,true,shiptp); + break; + case 3: + drawgrid(i,j,1,getlen(ship),true,shiptp); + break; + + } + } + } + } + butts.unpress(100 + i* 10 + j); + } else { + if(game == 1) { + if(turn) { + if (butts.state(i * 10 + j) & TOGGLE) { + if (( ofield[i][j] & 0b00010000) == 0) { + turn = !turn; + ofield[i][j] = ofield[i][j] | 0b00010000; + } + } + } + } else { + + } + butts.unpress(i * 10 + j); + } + j++; + } + i++; + } +} +void checkrotbutts() { + if (butts.state(201) & TOGGLE) { + butts.unpress(201); + dir++; + dir = dir % 4; + } + if (butts.state(202) & TOGGLE) { + butts.unpress(202); + dir--; + dir = (4 + dir) % 4; + } +} +void drawship (int x,int y, char data) { + char rdir = ((data & 0b11000000) >> 6); + char rship = data & 0b0000111; + switch(rdir) { + case 0: + drawgrid(x,y,getlen(rship),1,true,shiptp); + break; + case 1: + drawgrid(x,y - getlen(rship) + 1,1,getlen(rship),true,shiptp); + break; + case 2: + drawgrid(x - getlen(rship) + 1,y,getlen(rship),1,true,shiptp); + break; + case 3: + drawgrid(x,y,1,getlen(rship),true,shiptp); + break; + + } +} +void eraseship(int rship) { + int i = 0; + int j = 0; + while (i < 10) { + j = 0; + while (j < 10) { + if ((pfield[i][j] & 0b00000111) == rship ) { + pfield[i][j] = 0; + } + j++; + } + i++; + } +} +void checkships (bool player) { + int ships [5]; + int ri = 0; + while (ri < 5) { + ships[ri] = -1; + ri++; + } + int si = 0; + int ji = 0; + while (si < 10) { + ji = 0; + while (ji < 10) { + char peg; + if (player) { + peg = pfield[si][ji]; + } else { + peg = ofield[si][ji]; + } + if (peg & 0b00100000) { + //ships[((int)(peg & 0b00000111)) - 1] = 0; + if (ships[(peg & 0b00000111) - 1] == -1) { + ships[(peg & 0b00000111) - 1] = 0; + } + } + if ((peg & 0b00000111) && (peg & 0b00010000)) { + if (ships[(peg & 0b00000111) - 1] == -1) { + ships[(peg & 0b00000111) - 1] = 1; + } else { + ships[(peg & 0b00000111) - 1]++; + } + } + ji++; + } + si++; + } + bool allplaced = true; + ri = 0; + while (ri < 5) { + if (ships[ri] == -1 ) { + allplaced = false; + } + //printf("chcking ship %d with hitnum %d\n",ri+1,ships[ri]); + ri++; + } + if (allplaced) { + if (game == 0) { + if (player) { + game = 2; + } + } + bool allsunk = true; + ri = 0; + while (ri < 5) { + if (ships[ri] == getlen(ri + 1) ) { + if (!player) { + //to show whether a ship is down + drawtext(370,10 + 40 * ri,"X",red); + } else { + //your stuff + drawtext(370,500 + 40 * ri,"X",red); + } + } else { + allsunk = false; + } + ri++; + } + if (allsunk) { + if(player) { + game = -2; + } else { + game = -1; + } + } + } + //printf("game state:%d\n",game); +} +bool placeship(int rx, int ry, int rship,int rdir, bool player) { + int len = 0; + bool valid = true; + while (len < getlen(rship)) { + int x = rx; + int y = ry; + switch(rdir) { + case 0: + x+=len; + break; + case 1: + y-=len; + break; + case 2: + x-=len; + break; + case 3: + y+=len; + break; + } + if ((x < 0 )||(x >= 10)) { + valid = false; + } + if ((y < 0 )||(y >= 10)) { + valid = false; + } + if (pfield[x][y] & 0b111) { + if (player) { + valid = false; + } + } + if (ofield[x][y] & 0b111) { + if (!player) { + valid = false; + } + } + len++; + } + if (valid) { + //printf("placed a ship %d\n",rship); + len = 0; + while (len < getlen(rship)) { + int x = rx; + int y = ry; + switch(rdir) { + case 0: + x+=len; + break; + case 1: + y-=len; + break; + case 2: + x-=len; + break; + case 3: + y+=len; + break; + } + if (player) { + pfield[x][y] = rship | (rdir << 6); + } else { + ofield[x][y] = rship | (rdir << 6); + } + len++; + } + if (player) { + pfield[rx][ry] = (pfield[rx][ry] | 0b0100000); + } else { + ofield[rx][ry] = (ofield[rx][ry] | 0b0100000); + } + } + //printf("VALID:%d\n",valid); + return valid; + +} +void AI() { + //printf("R:%d\n",randr(0,9)); + if (game == 2) { + int i = 1; + while (i <= 5) { + bool valid = placeship(randr(0,9),randr(0,9),i,randr(0,3),false); + while (!valid) { + valid = placeship(randr(0,9),randr(0,9),i,randr(0,3),false); + } + i++; + } + game = 1; + } + if (game == 1) { + if(!turn) { + int score[30]; + int xs[30]; + int ys[30]; + int tscore = -99; + int tpick = -1; + int i = 0; + while (i < 30) { + bool valid = false; + while (!valid) { + int tx = randr(0,9); + int ty = randr(0,9); + if (( pfield[tx][ty] & 0b00010000) == 0) { + xs[i] = tx; + ys[i] = ty; + score[i] =getscore(tx,ty); + if (tpick == -1) { + tscore = score[i]; + tpick = i; + } else { + if (tscore < score[i]) { + tscore = score[i]; + tpick = i; + } + } + valid = true; + } else { + valid = false; + } + } + i++; + } + pfield[xs[tpick]][ys[tpick]] = pfield[xs[tpick]][ys[tpick]] | 0b00010000; + turn = !turn; + } + } + //printf("ai:%d\n",aihits); +} +int getscore(int x, int y) { + int score; + if (x < 9) { + char peg = pfield[x + 1][y + 0]; + if((peg & 0b00010000) != 0) { + if ((peg & 0b00000111) != 0) { + score += aihits / 5 + 3; + } else { + score--; + } + } else { + score += 2; + } + } + if (y < 9) { + char peg = pfield[x + 0][y + 1]; + if((peg & 0b00010000) != 0) { + if ((peg & 0b00000111) != 0) { + score += aihits / 5 + 3; + } else { + score--; + } + } else { + score += 2; + } + } + if (x > 0) { + char peg = pfield[x - 1][y + 0]; + if((peg & 0b00010000) != 0) { + if ((peg & 0b00000111) != 0) { + score += aihits / 5 + 3; + } else { + score--; + } + } else { + score += 2; + } + } + if (y > 0) { + char peg = pfield[x + 0][y - 1]; + if((peg & 0b00010000) != 0) { + if ((peg & 0b00000111) != 0) { + score += aihits / 5 + 3; + } else { + score--; + } + } else { + score += 2; + } + } + return score; +} +int randr(int min, int max) { + int r = (min + (random() /(( RAND_MAX - 1) / (max + 1)))); + //printf("r:%d,min:%d,max:%d\n",r,min,max); + return r; +} +std::string readfile(char const * filename) { + std::ifstream filebuffer; + std::string line; + std::string rstr; + rstr = ""; + char c; + filebuffer.open(filename); + if (!filebuffer.is_open()) { + printf("error reading file"); + } + while (filebuffer.get(c)) { + rstr = rstr + c; + } + filebuffer.close(); + return rstr; +} +void writefile(char const * filename, char data[10][10]) { + std::ofstream filebuffer; + filebuffer.open(filename); + if (!filebuffer.is_open()) { + printf("error reading file"); + } + int r = 0; + while (r < 10) { + filebuffer.write(data[r],10); + r++; + } + filebuffer.close(); +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..72682d3 --- /dev/null +++ b/main.h @@ -0,0 +1,20 @@ + +#ifndef MAIN_H +#define MAIN_H +extern int loop; +void drawgrid(int x, int y,int w,int h, bool player, SDL_Texture * t); +void drawfield(bool player); +void checkshipbutts(); +void checkfieldbutts(bool player); +void checkrotbutts(); +void drawship (int x,int y, char data); +int getlen(int ship); +void eraseship(int rship); +void checkships(bool player); +bool placeship(int rx, int ry, int rship, int rdir, bool player); +void AI(); +int randr(int min, int max); +int getscore(int x, int y); +std::string readfile(char const * filename); +void writefile(char const * filename, char data[10][10]); +#endif diff --git a/main.o b/main.o new file mode 100644 index 0000000..e8accd8 Binary files /dev/null and b/main.o differ diff --git a/makefile b/makefile new file mode 100644 index 0000000..9643478 --- /dev/null +++ b/makefile @@ -0,0 +1,6 @@ +main : main.o + g++ main.o -o main -L/home/knolax/code/cpp/gfx -lgui -lgfx -lSDL2 -lSDL2_ttf +main.o : main.cpp + g++ -c main.cpp -I/home/knolax/code/cpp/gfx +clean : + rm gfx.o main.o gui.o diff --git a/saveo b/saveo new file mode 100644 index 0000000..77c34de Binary files /dev/null and b/saveo differ diff --git a/savep b/savep new file mode 100644 index 0000000..73a7f52 Binary files /dev/null and b/savep differ diff --git a/so b/so new file mode 100644 index 0000000..3c4932e Binary files /dev/null and b/so differ -- cgit v1.1