Programeer opdrachtenOpdracht : opdr1_tim.txt

Terug naar de inzendingen
Opdracht 1, Tim Cooijmans
13 Jan 2005
 
 1 
 ******** automaat.h ***********
  
 2#ifndef _AUTOMAAT_H_
 3 #define _AUTOMAAT_H_
 4
 5#include "global.h"
 6
 7int  s_minder_dan_vijf (int);
 8int  s_meer_dan_tien  (int);
 9
 10void v_werp_uit   (int v_type);
 11void m_vul_bij   (int m_type);
 12void m_werp_uit   (int m_type);
 13
 14#endif // _AUTOMAAT_H_
 15
 1 
******** error.h ***********
  
 2#ifndef _ERROR_H_
 3 #define _ERROR_H_
 4
 5#include "global.h"
 6
 7struct _error  {
 8 char message[50];
 9};
 10
 11void error (int e_code);
 12
 13#endif // _ERROR_H_
 14
 1 
******** global.h ***********
  
 2#ifndef _GLOBAL_H_
 3 #define _GLOBAL_H_
 4
 5#include 
 6#include 
 7
 8/* Global enums     */
 9
 10/* Typen snoep: 0 = retour  */
 11enum    {
 12 V_RETOUR,
 13 V_DROP,
 14 V_KATJESDROP,
 15 V_ENGELSEDROP,
 16 V_PEPERMUNT,
 17 V_CHOCOLADE,
 18 V_AANTAL
 19} v_types;
 20
 21/* Typen munten: 0 = naar keuze */
 22enum    {
 23 M_KEUZE,
 24 M_C_VIJF,
 25 M_C_TIEN,
 26 M_C_TWINTIG,
 27 M_C_VIJFTIG,
 28 M_E_EEN,
 29 M_E_TWEE,
 30 M_AANTAL
 31} m_types;
 32
 33/* Error codes: zie error.c  */
 34enum    {
 35 E_INTERN,
 36 E_WISSEL,
 37 E_VOORRAAD,
 38 E_AANTAL
 39} e_codes;
 40
 41/* Engine headers  */
 42#include "error.h"
 43#include "voorraad.h"
 44#include "wissel.h"
 45#include "automaat.h"
 46
 47#endif // _GLOBAL_H_
 48
 1 
******** voorraad.h ***********
  
 2#ifndef _VOORRAAD_H_
 3 #define _VOORRAAD_H_
 4
 5#include "global.h"
 6
 7struct _voorraad {
 8 int  aantal;
 9 char naam [15];
 10 int  prijs;  /* In centen */
 11};
 12
 13int  v_valid_type (int v_type);
 14int  v_get_prijs  (int v_type);
 15int  v_get_aantal (int v_type);
 16char * v_get_naam  (int v_type);
 17void v_dec_aantal (int v_type);
 18
 19void geef_menu_weer (void);
 20
 21#endif // _VOORRAAD_H_
 22
 1 
******** wissel.h ***********
  
 2#ifndef _WISSEL_H_
 3 #define _WISSEL_H_
 4
 5struct _munt  {
 6 int  waarde;
 7 int  schatting; /* Schatting van het aantal munten in de buizen.
 8       Op het moment dat een buis' aantal onder de 5 dropt
 9       of niet langer >10 is, wordt de schatting van zijn
 10       default waarde (-1) gehaald, en kan de schatting
 11       als betrouwbaar worden gezien     */
 12 
 13 // private
 14 int  aantal;
 15};
 16
 17int  minder_dan_vijf  (int m_type);
 18int  meer_dan_tien  (int m_type);
 19
 20int  m_valid_type  (int m_type);
 21int  m_type_van_waarde (int m_waarde);
 22int  m_get_waarde  (int m_type);
 23
 24int  m_get_aantal  (int m_type);
 25int  m_dec_aantal  (int m_type);
 26int  m_inc_aantal  (int m_type);
 27
 28int  m_get_schatting  (int m_type);
 29void m_inc_schatting  (int m_type);
 30void m_dec_schatting  (int m_type);
 31
 32void wissel    (int bedrag);
 33void wissel_munt   (int m_type);
 34
 35#include "global.h"
 36
 37#endif // _WISSEL_H_
 38
 1 
******** automaat.c ***********
  
 2/*
 3 * Snoepautomaat v1.0
 4 * Tim Cooijmans 2005
 5 * http://forum.nedlinux.nl/viewtopic.php?t=16405
 6 * 
 7 * automaat.c: Automaatsimulatie.
 8 *  sensors & in- en uitworp
 9 */
 10
 11#include "automaat.h"
 12
 13/*
 14 * Sensor: minder dan vijf munten in de buis?
 15 */
 16int  s_minder_dan_vijf (int m_type) {
 17 if (!m_valid_type (m_type))  error (E_INTERN);
 18 
 19 return (m_get_aantal (m_type) < 5);
 20}
 21
 22/*
 23 * Sensor: meer dan tien munten in de buis?
 24 */
 25int  s_meer_dan_tien  (int m_type) {
 26 if (!m_valid_type (m_type))  error (E_INTERN);
 27 
 28 return (m_get_aantal (m_type) > 10);
 29}
 30
 31/*
 32 * Munt uitwerpen en dat laten weten
 33 */
 34void m_werp_uit   (int m_type) {
 35 if (!m_valid_type (m_type))  error (E_INTERN);
 36 
 37 if (!m_get_aantal (m_type))  error (E_WISSEL);
 38 
 39 m_dec_aantal (m_type);
 40 
 41 printf ("%.2f euro uitgeworpen\n", m_get_waarde (m_type) / 100.00);
 42}
 43
 44/*
 45 * Munt ingeworpen: in buis gooien
 46 */
 47void m_vul_bij   (int m_type) {
 48 if (!m_valid_type (m_type))  error (E_INTERN);
 49 
 50 m_inc_aantal (m_type);
 51}
 52
 53/*
 54 * Product uitwerpen en dat laten weten
 55 */
 56void v_werp_uit   (int v_type) {
 57 if (!v_valid_type (v_type))  error (E_INTERN);
 58 
 59 v_dec_aantal (v_type);
 60 
 61 printf ("%s uitgeworpen. Smakelijk he!\n", v_get_naam (v_type));
 62}
 63
 1 
******** error.c ***********
  
 2/*
 3 * Snoepautomaat v1.0
 4 * Tim Cooijmans 2005
 5 * http://forum.nedlinux.nl/viewtopic.php?t=16405
 6 * 
 7 * error.c: Error handling.
 8 *  struct array met error messages die geprint worden indien er een fout
 9 *  optreedt
 10 */
 11
 12#include "error.h"
 13
 14struct _error e[] = {
 15 { "Interne programmeerfout.\n" }, /* Foutieve ?_type variabelen e.d:
 16           programmeerfout dus    */
 17 { "Wisselgeld op.\n"   }, /* Indien het wisselgeld op is  */ 
 18 { "Voorraad op.\n"    }, /* Indien de snoep op is   */
 19 { "" }
 20};
 21
 22/*
 23 * Rigoreuze error handling: een typische melding en een laffe exit ;)
 24 */
 25void error (int e_code) {
 26 /* Als zelfs e_code ongeldig is, dan gooi er maar een E_INTERN tegenaan */
 27 if (e_code < 0 || e_code > E_AANTAL) {
 28  e_code = E_INTERN;
 29 }
 30 
 31 printf (
 32  "\n\n\a"
 33  "Deze automaat is tijdelijk buiten gebruik. "
 34  "Er is een fout opgetreden: %s\n"
 35   , e[e_code].message);
 36 exit (e_code);
 37}
 38
 1 
******** interface.c ***********
  
 2/*
 3 * Snoepautomaat v1.0
 4 * Tim Cooijmans 2005
 5 * http://forum.nedlinux.nl/viewtopic.php?t=16405
 6 * 
 7 * interface.c: User interface.
 8 *  main loop & inworp/keuze modes
 9 */
 10
 11#include "global.h"
 12
 13int  accepteer_inworp (void);
 14void accepteer_keuze  (int);
 15int  prompt_inworp  (void);
 16int  prompt_keuze  (void);
 17
 18/*
 19 * Oneindige loop die menu weergeeft en een sessie afhandelt (inworp & keuze)
 20 */
 21int  main (void) {
 22 int saldo;
 23 while (1) {
 24  geef_menu_weer ();
 25  
 26  saldo = accepteer_inworp ();
 27  accepteer_keuze    (saldo);
 28 }
 29}
 30
 31/*
 32 * Prompt voor inworp & keuze: ja, van deze twee functies had ik natuurlijk
 33 * ook een vieze void-pointerconstructie kunnen bakken, maar dan maar zo :P
 34 */
 35int  prompt_inworp (void)   {
 36 float f = 0;
 37 
 38 printf ("inworp> ");
 39 fflush (stdout);
 40 
 41 scanf ("%f", &f);
 42 
 43 int i = (f * 100);
 44 return i;
 45}
 46
 47int  prompt_keuze (void)   {
 48 int i = 0;
 49 
 50 printf ("keuze> ");
 51 fflush (stdout);
 52 
 53 scanf ("%i", &i);
 54 
 55 return i;
 56}
 57
 58/*
 59 * Accepteer inworp: wacht op inworp tot de 0 gekozen wordt
 60 */
 61int  accepteer_inworp  (void) {
 62 int  saldo = 0;
 63 int  inworp = 0;
 64 int  m_type = 0;
 65 
 66 inworp = prompt_inworp ();
 67 while (inworp != 0) {
 68  if (inworp ==  5 || inworp ==  10 || inworp ==  20 ||
 69   inworp == 50 || inworp == 100 || inworp == 200) {
 70   saldo += inworp;
 71   
 72   m_type = m_type_van_waarde (inworp);
 73   m_vul_bij (m_type);
 74   m_inc_schatting (m_type);
 75   
 76   printf ("Saldo: %.2f\n", saldo / 100.00);
 77  } else {
 78   printf ("Ongeldige inworp: %.2f. "
 79     "Geldige inworpen zijn:\n"
 80     "0.05, 0.10, 0.20, 0.50, 1.00 en 2.00 euro"
 81     " of 0 om een keuze te maken\n"
 82     , inworp / 100.00);
 83   
 84   inworp = prompt_inworp ();
 85   continue;
 86  }
 87  
 88  inworp = prompt_inworp ();
 89 }
 90 
 91 return saldo;
 92}
 93
 94void accepteer_keuze  (int saldo) {
 95 int keuze;
 96 
 97 geef_menu_weer ();
 98 
 99 keuze = prompt_keuze ();
 100 while (!v_valid_type (keuze)) {
 101  printf ("Ongeldige keuze: %i\n", keuze);
 102  
 103  keuze = prompt_keuze ();
 104 }
 105 
 106 if (keuze == V_RETOUR) {
 107  printf ("Inworp retour.\n");
 108  wissel (saldo);
 109  
 110  return;
 111 }
 112 
 113 if (!v_get_aantal (keuze)) {
 114  printf ("Inworp retour: product niet op voorraad.\n");
 115  wissel (saldo);
 116  
 117  return;
 118 }
 119 
 120 if (saldo < v_get_prijs (keuze)) {
 121  printf ("Inworp retour: saldo ontoereikend.\n");
 122  wissel (saldo);
 123  
 124  return;
 125 } else if (saldo > v_get_prijs (keuze)) {
 126  /* Wisselgeld teruggeven */
 127  wissel (saldo - v_get_prijs (keuze));
 128 }
 129 
 130 /* En uitwerpen die hap!  */
 131 v_werp_uit (keuze);
 132 
 133 return;
 134}
 135
 1 
******** voorraad.c ***********
  
 2/*
 3 * Snoepautomaat v1.0
 4 * Tim Cooijmans 2005
 5 * http://forum.nedlinux.nl/viewtopic.php?t=16405
 6 * 
 7 * voorraad.c: Snoepvoorraad.
 8 *  struct array met functies om deze array te manipuleren & menuweergave
 9 */
 10
 11#include "voorraad.h"
 12
 13struct _voorraad v[] = {
 14 { 0, "Retour",  -1 },
 15 /* Aant. Naam (14c max) Prijs */
 16   /**************/
 17 { 10, "Drop",    75 },
 18 { 10, "Katjesdrop", 125 },
 19 { 10, "Engelse drop", 150 },
 20 { 10, "Pepermunt",  75 },
 21 { 10, "Chocolade", 100 }
 22};
 23
 24/*
 25 * Geldig typenummer?
 26 */
 27int  v_valid_type (int v_type) {
 28 return (v_type >= 0 && v_type < V_AANTAL);
 29}
 30
 31/*
 32 * Getters & setters: lijkt me duidelijk. In deze categorie kan ik overigens
 33 * nog uren doorgaan, maar dit is wat ik nodig had, dus ga ik de consistentie
 34 * even achterwege laten ;)
 35 */
 36int  v_get_prijs  (int v_type) {
 37 if (!v_valid_type (v_type))  error (E_INTERN);
 38 
 39 return v[v_type].prijs;
 40}
 41
 42int  v_get_aantal (int v_type) {
 43 if (!v_valid_type (v_type))  error (E_INTERN);
 44 
 45 return v[v_type].aantal;
 46}
 47
 48char * v_get_naam  (int v_type) {
 49 if (!v_valid_type (v_type))  error (E_INTERN);
 50 
 51 return v[v_type].naam;
 52}
 53
 54void v_dec_aantal (int v_type) {
 55 if (!v_valid_type (v_type))  error (E_INTERN);
 56 
 57 --v[v_type].aantal;
 58}
 59
 60/*
 61 * Duh
 62 */
 63void geef_menu_weer (void)  {
 64 printf (
 65  "Welkom bij de snoepautomaat voor echte mannen!\n"
 66  "Werp geld in, en druk vervolgens op '0' om uw "
 67  "keuze te maken. Indien u twee keer '0' toetst, "
 68  "krijgt u uw inworp terug.\n\n"
 69   );
 70 
 71 /* Hier passen we even dezelfde uitlijning toe als bij de variabelen */
 72 printf ("%6s\t%14s\t%s\n", "nummer", "product", "prijs");
 73 int v_type = 1;
 74 for (; v_type < V_AANTAL; v_type++) {
 75  printf (
 76   "%6i\t%14s\t%.2f\n",
 77   v_type,
 78   v_get_naam (v_type),
 79   v_get_prijs (v_type) / 100.00
 80  );
 81 }
 82}
 83
 1 
******** wissel.c ***********
  
 2/*
 3 * Snoepautomaat v1.0
 4 * Tim Cooijmans 2005
 5 * http://forum.nedlinux.nl/viewtopic.php?t=16405
 6 * 
 7 * wissel.c: Muntensysteem.
 8 *  struct array die de muntenvoorraad representeert met functies om deze
 9 *  te manipuleren & wissellogica
 10 */
 11
 12#include "wissel.h"
 13
 14struct _munt  m[] = {
 15 { 0, 0, 0 },
 16 {   5, -1, 15 },
 17 {  10, -1, 15 },
 18 {  20, -1, 15 },
 19 {  50, -1, 15 },
 20 { 100, -1, 15 },
 21 { 200, -1, 15 }
 22};
 23
 24int  minder_dan_vijf  (int m_type) {
 25 if (s_minder_dan_vijf (m_type)) {
 26  if (m[m_type].schatting == -1) { /* Nog niet bekend?   */
 27   m[m_type].schatting = 4;  /* Dan nu wel    */
 28  }
 29  
 30  return 1;
 31 }
 32 
 33 return 0;
 34}
 35
 36int  meer_dan_tien  (int m_type) {
 37 if (!s_meer_dan_tien (m_type)) {
 38  if (m[m_type].schatting == -1) { /* Nog niet bekend?   */
 39   m[m_type].schatting = 10;  /* Dan nu wel    */
 40  }
 41  
 42  return 1;
 43 }
 44 
 45 return 0;
 46}
 47
 48/*
 49 * Als er een munt in- of uitgeworpen wordt, moet de schatting up-to-date
 50 * blijven.
 51 */
 52void m_inc_schatting  (int m_type) {
 53 if (!m_valid_type (m_type))     error (E_INTERN);
 54 
 55 if (m[m_type].schatting != -1)   /* Moet-ie wel bekend zijn */
 56  m[m_type].schatting++;
 57}
 58
 59void m_dec_schatting  (int m_type) {
 60 if (!m_valid_type (m_type))     error (E_INTERN);
 61 
 62 if (m[m_type].schatting != -1)   /* Moet-ie wel bekend zijn */
 63  m[m_type].schatting--;
 64}
 65
 66int  m_get_schatting  (int m_type) {
 67 if (!m_valid_type (m_type))     error (E_INTERN);
 68 
 69 return m[m_type].schatting;
 70}
 71
 72/*
 73 * Geldig typenummer?
 74 */
 75int  m_valid_type  (int m_type) {
 76 return (m_type >= 0 && m_type < M_AANTAL);
 77}
 78
 79/*
 80 * Haal van een waarde het muntnummer op
 81 */
 82int  m_type_van_waarde (int m_waarde) {
 83 int i = 1;
 84 for (; i < M_AANTAL; i++) {
 85  if (m_get_waarde (i) == m_waarde) return i;
 86 }
 87 
 88 return 0;
 89}
 90
 91int  m_get_waarde  (int m_type) {
 92 if (!m_valid_type (m_type))     error (E_INTERN);
 93 
 94 return m[m_type].waarde;
 95}
 96
 97/* Deze functies mogen alleen vanuit automaat.c worden gebruikt */
 98int  m_inc_aantal  (int m_type) {
 99 if (!m_valid_type (m_type))     error (E_INTERN);
 100 
 101 return m[m_type].aantal++;
 102}
 103
 104int  m_dec_aantal  (int m_type) {
 105 if (!m_valid_type (m_type))     error (E_INTERN);
 106 
 107 return m[m_type].aantal--;
 108}
 109
 110int  m_get_aantal  (int m_type) {
 111 if (!m_valid_type (m_type))     error (E_INTERN);
 112 
 113 return m[m_type].aantal;
 114}
 115/********************************************************************/
 116
 117/*
 118 * Wissel een bepaald bedrag: nothing fancy, gewoon in zo groot mogelijke
 119 * munten uitbetalen. Dat is namelijk mijns insziens ook het meest efficient.
 120 */
 121void wissel    (int bedrag) {
 122 const int b = bedrag; /* Kopietje voor later */
 123 
 124 /* Grootste munt eerst */
 125 int munt = M_AANTAL-1;
 126 int waarde = 0;
 127 
 128 /* Voor iedere munt  */
 129 for (; munt > 0; munt--) {
 130  if (!m_valid_type (munt)) continue;
 131  waarde = m_get_waarde (munt);
 132  
 133  /* Zo vaak deze munt in het bedrag past en we de munt op voorraad
 134   hebben (schatting onbekend? dan naar die poepsensors kijken) */
 135  while (
 136   (bedrag - waarde) >= 0 &&
 137   (m_get_schatting (munt) > 0 || !minder_dan_vijf (munt))
 138    ) {
 139   bedrag -= waarde;
 140   
 141   wissel_munt (munt);
 142  }
 143 }
 144 
 145 printf ("In totaal %.2f euro wisselgeld uitgeworpen.\n", b / 100.00);
 146}
 147
 148void wissel_munt   (int m_type) {
 149 if (!m_valid_type (m_type))     error (E_INTERN);
 150 
 151 m_werp_uit (m_type);
 152 m_dec_schatting (m_type);
 153 
 154 /* Hier draaien we even de sensor-checkers, indien mogelijk maken deze een
 155  schatting van het aantal munten in de buis */
 156 minder_dan_vijf (m_type);
 157 meer_dan_tien (m_type);
 158}
 
 
Mijn commentaar
 
 Tim,
 Je coding style brengt bij mij enige verwarring.
 Het gebruik van tabs wordt welliswaar door een aantal editors afgedwongen,
 maar levert regelmatig problemen met andere editors op !
 Je error handling module sugereerd dat de snoepkast onder een UNIX/Linux besturings systeem draait.
 Ik ga er toch maar van uit dat het in werkelijkheid een eenvoudig embedded systeempje is.
 Helaas maak je niet echt een onderscheid tussen de simulatie van de automaat en
 je besturings logica.
 Zoals ik je al aangaf mis in duidelijke compileer instructies of een make file.
 Al met al een heel aardige bijdrage, hoop dat je volgende keer weer mee doet.