Tentamen: Datordel Programmeringsteknik Datum: 2013-01-16 Tid: 9:00-14:00 Sal: Ansvarig: Resultat: Hjälpmedel: Betygsgränser: Ulf Johansson Anslås inom 3 veckor. Inga Sammanlagt 30 p för G, 45 p för VG. Iakttag följande: Arbeta i ett enda projekt. Observera att den c-kod som lämnas in skall vara körbar, dvs. ni måste kompilera om efter er sista ändring i koden och kontrollera att den slutgiltiga koden inte ger kompileringsfel. Kod som inte fungerar måste därför vara bortkommenterad. Endast det som ligger i respektive projektmapp kommer att bedömas. Lösningarna rättas i befintligt skick. Såväl funktionalitet som struktur bedöms, vilket innebär att: även en lösning som inte är fullständig kan ge poäng poängavdrag kan ges för onödigt komplicerade eller ostrukturerade lösningar Koden behöver endast kommenteras när det står så i uppgiften. Kommandon från bibliotek (även Roberts) får användas fritt.
1) I denna uppgift skall du skriva ett program som låter användaren spela ett litet gissningsprogram, där datorn tänker på ett hemligt tal som användaren skall gissa. Det hemliga talet skall slumpas fram. De intervall som talet ligger i skall definieras med konstanter. Ett tips är att först skriva programmet utan slumpmässighet för att kunna testköra på ett kontrollerat sätt. a) I det första steget skall du implementera spelet i sin ursprungliga variant, enligt nedanstående: Programmet behöver inte utföra felkontroll på inmatat tal. När användaren gissat skall programmet ange om gissningen är över eller under det hemliga talet eller om det är korrekt. Gissandet fortsätter tills användaren gissat rätt tal. Programmet skall då ange hur många gissningar spelaren behövde för att gissa talet. Programmet skall endast köra spelet en omgång. Körningsexempel: This program plays the game of Hi-Lo. 50 25 37 44 47 45 Correct. You guessed the number in 6 tries. Press any key to continue... b) I detta steg skall vi införa en liten twist, som innebär att den som gissar får en ledtråd till talet genom att datorn, i första omgången, anger summan av siffrorna i talet. Om det hemliga talet till exempel är 83, så är siffersumman 11, och programmet skall inledas med att detta anges. Datorn skall också räkna ut summan av siffrorna för varje gissning som användaren ger och ange detta, samt hur det räknas ut, på det format som visas i körningsexemplet nedan. Programmet skall uppfylla följande krav: Det skall struktureras så att funktionen för att räkna ut siffersumman kan återanvändas när uträkningen skall visas. Funktionen för att räkna ut siffersumman skall fungera för godtyckligt stora tal. Funktionen för att visa uträkningen behöver bara kunna hantera tal med 1-3 siffror, dvs. i intervallet 0-999. Strängfunktioner skall användas att ta fram sifforna i talet. Tänk på att det finns en funktion för att omvandla heltal till strängar: IntegerToString.
Körningsexempel: This program plays the game of Hi-Lo. The digit sum of the secret number is 8. 100 The digit sum of your guess is 1+0+0=1. 50 The digit sum of your guess is 5+0=5. 75 The digit sum of your guess is 7+5=12. 53 The digit sum of your guess is 5+3=8. 62 The digit sum of your guess is 6+2=8. 71 The digit sum of your guess is 7+1=8. Correct. You guessed the number in 6 tries. Press any key to continue... (15 p)
2) I den här uppgiften skall vi arbeta med vektorer och ett berömt spel som heter Nim. I Nim finns ett antal staplar med mynt (kan även vara högar av tändstickor), där spelarna turas om att ta bort mynt från spelet tills endast ett mynt återstår. Den spelare som tar sista myntet förlorar. I ett visst drag får spelaren ta hur många mynt som helst, men bara från en stapel. Oftast låter man antalet staplar vara 3, 6 eller 9 och antalet mynt från början någonstans mellan 1 och 15 i varje stapel. Vi väljer att representera spelbrädet, dvs. de olika staplarna, som en heltalsvektor kallad board där varje index motsvarar en stapel och värdet utgör antalet mynt. Exempelvis motsvarar vektorn nedan att spelet består av tre staplar där det ligger 3, 4 respektive 7 mynt i de olika staplarna. Med andra ord är board[0]=3, board[1]=4 och board[2]=7. Index 0 1 2 Värde 3 4 7 Vi tänker oss här att den här filen egentligen är en del av en modul, varför vi kan använda oss av static-deklarerade variabler. Mer konkret låter vi alltså såväl board som size (antalet staplar) vara static-deklarerede. Notera att vi alltså för enkelhets skull nu på tentan ändå skriver all kod (inklusive main) i en enda fil, varför vi alltså inte behöver ha någon h-fil eller dela upp programmet över flera filer på något annat sätt. Eftersom vi arbetar top-down har vi börjat med att skriva main se nedan. Det som återstår är alltså att skriva de övriga fem funktionerna som binder ihop programmet. Observera att ett helt körningsexempel finns sist i uppgiften. main(){ Randomize(); initgame(); while(true){ if(endofgame()){ printf("human Wins\n"); break; printboard(); humanplay(); if(endofgame()){ printf("cpu Wins\n"); break; printboard(); cpuplay(); c) I första steget skall ni skapa funktionen initgame vilken dynamiskt allokerar en heltalsvektor (board) av rätt storlek. Storleken skall slumpas och vara ett av värdena 3, 6 eller 9. Självklart skall den static-deklarerade variabeln size också sättas till den slumpade storleken. Slutligen skall antalet mynt i de olika staplarna slumpas mellan 1 och 15. d) Nästa funktion är printboard, vilken helt enkelt skriver ut läget i spelet just nu. e) Därefter tar vi oss an endofgame, vilken skall returnera sant om spelet är slut, dvs. om det inte finns något mynt kvar i någon stapel.
f) Funktionen humanplay låter en användare först mata in vilken stapel, samt därefter hur många mynt spelaren väljer att ta. Om draget inte är tillåtet skall spelaren få information om detta och därefter få göra om draget. Programmet måste alltså ha en rimlig felkontroll, dvs. det får inte krascha eller avslutas bara för att användaren försöker göra ett felaktigt drag. Exempel på felaktiga drag som skall pareras av programmet är att välja en stapel som inte finns eller att försöka ta fler mynt än möjligt från en viss stapel. Funktionen skall slutligen skriva ut det resulterande draget, samt förstås uppdatera board. g) I sista steget skall vi koda en datorspelare. Datorspelarens strategi, om den kan kallas för det, är väldigt simpel: Så länge inte alla staplar innehåller 0 eller 1 mynt så väljer datorn en stapel, bland de som har fler än 1 mynt, slumpmässigt. Datorn tar sedan bort alla mynt utom 1 från denna stapel. Om alla staplar har 0 eller 1 mynt så tar datorn bort myntet från den första stapeln som har ett mynt. Koda nu funktionen cpuplay utifrån denna strategi! (Tips: Om ni inte lyckas få till datorspelaren så kan ni för att kunna testa hela programmet helt enkelt låta även datorns drag göras av en mänsklig spelare dvs. ni ändrar i så fall bara anropet i main. Detta ger förstås inte full poäng på uppgiften, men är som sagt ett sätt att i alla fall kunna köra hela programmet.) Körningsexempel: 4 4 14 Which pile? 2 How many coins? 3 Human removes 3 coins from pile 2 4 1 14 CPU removes 3 coins from pile 1 1 1 14 Which pile? 3 How many coins? 13 Human removes 13 coins from pile 3 1 1 1 CPU removes 1 coins from pile 1 0 1 1 Which pile? 2 How many coins? 1 Human removes 1 coins from pile 2 0 0 1 CPU removes 1 coins from pile 3 Human Wins Press any key to continue... (15 p)
3) Denna uppgift syftar till att skapa ett enkelt register med utnyttjande av poster (structar) och dynamisk minnesallokering. Följ arbetsstegen nedan. a) Skriv en typdefinition för en post (struct) som representerar en bok. Posten skall innehålla boktitel, isbn (anges som en textsträng), antal sidor och genre (anges också som en textsträng). Dessutom skall det finnas en statisk vektor av storlek 3 för författare. Structen skall vara av pekartyp. b) Ge typdefinitionen för en struct innehållande en statisk vektor av böcker (storlek 50 som ges av konstant SIZE) och två heltal för att hålla reda på vektorns storlek och antal utnyttjade celler. Även denna struct skall vara av pekartyp. c) Skriv nu ett huvudprogram där ni deklarerar en variabel av den nya databastypen, allokerar minne och initialiserar den. d) Skriv en funktion getbookfromuser som från användaren tar in alla uppgifter för en bok och returnerar den nya boken. Fundera igenom vilken prototyp denna funktion skall ha innan du kodar! Inmatning av de 3 författarna kan göras direkt i en loop där användaren helt enkelt får ange en tom sträng för ett eller flera värden. Se körningsexempel nedan. e) Skriv en funktion som lägger in en bok på första lediga index i vektorn och uppdaterar relevanta variabler i databasstructen. Ni behöver inte kontrollera om vektorn är full. f) Skriv en funktion som tar in en bok som argument och skriver ut titel och författare till denna bok. Ni behöver inte lägga tid på att optimera utskriften med kommatecken etc. g) Skriv en funktion showbooksingenre som låter användaren mata in en genre och som skriver ut titel och författare för alla böcker i denna genre. h) Utöka slutligen huvudprogram för att knyta ihop det hela så att det går att köra som nedanstående exempel. Det skall naturligtvis inte finnas några menyer etc., utan bara några anrop till getbookfromuser för att mata in data i registret och ett test av showbooksingenre. (15 p) Exempelkörning: Welcome to the library application! Please input book details. Title: Algorithmics - The Spirit of Computing ISBN: 0-321-11784-0 Number of pages: 513 Genre: Computer Science Author no 1: Harel Author no 2: Feldman Author no 3: Please input book details. Title: The Art and Science of C ISBN: 0-201-54322-2 Number of pages: 704 Genre: Computer Science Author no 1: Roberts Author no 2: Please input book details. Title: Pride and Prejudice and Zombies ISBN: 9781594743344 Number of pages: 320
Genre: Spoof Author no 1: Austen Author no 2: Grahame-Smith Author no 3: Please input a genre (such as crime or romance): Computer Science Title: Algorithmics - The Spirit of Computing Authors: Harel, Feldman Title: The Art and Science of C Authors: Roberts Press any key to continue.