/* Johan Rydén DVP 1 Inlämnings uppgift 2 */#include<stdbool.h>#include<stdio.h>#include<stdlib.h>#include "cardpile.h"#include "ansi.h"/*RND(min,max) Genrearslumptalintervalet[min,max). */#define RND(min,max) (int)((rand()/((double)RAND_MAX+1))*(max-min)+(min));/* true om korten har samma färg annars false (eller kaboom) */bool colormatch(suit_t s1, suit_t s2) { int a=0; int b=0; switch(s1) { case DIAMONDS: a=1; break; case HEARTS: a=1; break; case CLUBS: a=2; break; case SPADES: a=2; break; default: fprintf(stderr, "Wrong value at line %d in file %s \n",__LINE__,__FILE__); exit(EXIT_FAILURE); } switch(s2) { case DIAMONDS: b=1; break; case HEARTS: b=1; break; case CLUBS: b=2; break; case SPADES: b=2; break; default: fprintf(stderr, "Wrong value at line %d in file %s \n",__LINE__,__FILE__); exit(EXIT_FAILURE); } return (a == b); } /* Konverterar kortets typ till en char (eller kaboom om det inte är en riktig typ) */char suittochar(suit_t suit) { switch(suit) { case DIAMONDS: return 'D'; break; case HEARTS: return 'H'; break; case CLUBS: return 'C'; break; case SPADES: return 'S'; break; default: fprintf(stderr, "Wrong value at line %d in file %s \n" ,__LINE__,__FILE__); exit(EXIT_FAILURE); } } /* Konverterar kortets värde till en char* (eller kaboom om det inte är en riktig typ) */char *ranktostring(rank_t rank) { switch(rank) { case TWO: return "2"; break; case THREE: return "3"; break; case FOUR: return "4"; break; case FIVE: return "5"; break; case SIX: return "6"; break; case SEVEN: return "7"; break; case EIGHT: return "8"; break; case NINE: return "9"; break; case TEN: return "10"; break; case JACK: return "J"; break; case QUEEN: return "Q"; break; case KING: return "K"; break; case ACE: return "A"; break; default: fprintf(stderr, "Wrong value at line %d in file %s \n" ,__LINE__,__FILE__); exit(EXIT_FAILURE); } } /* plockar ut värdet på nästa kort med undantag för kung som blir ess (eller kaboom om det inte är en riktig typ) */rank_t successor(rank_t rank) { switch(rank) { case TWO: return THREE; break; case THREE: return FOUR; break; case FOUR: return FIVE; break; case FIVE: return SIX; break; case SIX: return SEVEN; break; case SEVEN: return EIGHT; break; case EIGHT: return NINE; break; case NINE: return TEN; break; case TEN: return JACK; break; case JACK: return QUEEN; break; case QUEEN: return KING; break; case KING: return ACE; break; case ACE: return TWO; break; default: fprintf(stderr, "Wrong value at line %d in file %s \n" ,__LINE__,__FILE__); exit(EXIT_FAILURE); } } /* Skriver ut en korthög, ingen felhantering så var snäll mot den */void printcardpile(card_t* pile){ if (pile==EMPTY) printcard(pile); while(pile!=EMPTY) { printcard(pile); pile=pile->next; } printf(ANSI_CLEARLINE "\n");}/* Skriver ut en räknar korten i en hög, ingen felhantering så var snäll mot den */int countcards(card_t* pile){ int counter=0; if(pile==EMPTY) return(0); while(pile!=EMPTY) { counter++; pile=pile->next; } return(counter);}/* avmarkerar alla kort i en hög och ger false om den inte avmarkerade något, ingen felhantering så var snäll mot den */bool unmarkpile(card_t* pile){ bool x=false; if (pile==EMPTY) return(x); while(pile!=EMPTY) { if(COURSE_getmark(pile)==true) { COURSE_setmark(pile,false); x=true; } pile=pile->next; } return(x);}/* Skriver ut ett kort, jag ville helst skriva den med en ordentig printf men jag fattar inte riktigt hur man ska skriva dens automatiska bredd hantering. Den skapade också många debuggind problem, checklista för framtiden: Först kolla att strukturen är där, sen kolla om värdet ska visas, sen får du skriva ut värdet */void printcard(card_t* card){ char* z=ANSI_GREEN; if (card==EMPTY) { printf(" "); return; } if (card->visible==false) { printf("%s[****]",z); return; } if (card!=EMPTY) { rank_t rank=card->rank; suit_t suit=card->suit; char x=suittochar(suit); if (x=='H' || x=='D') z=ANSI_RED; else z=ANSI_BLACK; switch(rank) { case ACE: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case TWO: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case THREE: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case FOUR: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case FIVE:printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case SIX:printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case SEVEN: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case EIGHT:printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case NINE: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case TEN:printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case JACK: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case QUEEN: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; case KING: printf( "%s[%c: %s]",z,x,ranktostring(rank)); break; default: fprintf(stderr, "Wrong value at line %d in file %s \n",__LINE__,__FILE__); exit(EXIT_FAILURE); } }}/* Simpel men funkar, stoppar in (*pile) i next och card i (*pile) */void placeontop(card_t** pile, card_t* card){ card->next=(*pile); (*pile)=card;}/* De flesta borde förstå av att läsa den :P, flyttar pile till next och tar bort next från kortet */card_t* drawone(card_t** pile){ if ((*pile)==EMPTY) { return(EMPTY); } else { card_t* x= (*pile); (*pile)=(*pile)->next; x->next=EMPTY; return(x); } }/* don't ask */void shuffle(card_t** pile){ if (*pile==EMPTY) return; else { card_t** x=pile; int t=countcards(*pile); card_t** kortlek=(card_t**)malloc(sizeof(card_t*) * t); int i; int platsN=0; int platsR=0; card_t* z=(*pile); for(i = 0; i<t; i++) { kortlek[i] = (*x); (*x)=(*x)->next; } while(platsN<t) { platsR=RND(0, t); z=kortlek[platsN]; kortlek[platsN]=kortlek[platsR]; kortlek[platsR]=z; platsN++; } (*pile)=EMPTY; i=platsN-1; while (i>=0) { placeontop(pile,kortlek[i]); i--; } }}/*idén är att den ska flytta hela högen samtidigt genom att flytta botten kortet, sen länkar man top kortet till pile och voila :P */void movemarked(card_t** from, card_t** to){ card_t* x; card_t* y; if ((*from)==EMPTY) return; x=(*from); if(COURSE_getmark(x)==false) return; y=x->next; while((y)!=EMPTY) { if(COURSE_getmark(y)==false) { placeontop(to,x); (*to)=(*from); (*from)=y; unmarkpile(*to); return; } x=x->next; y=y->next; } if (y==EMPTY) { placeontop(to,x); (*to)=(*from); (*from)=y; unmarkpile(*to); return; }}