Printa stora bokstäver på skärmen
Hej!
En uppgift är att jag ska printa ut bokstäver på skärmen. Jag har skapat bokstaven A samt B och ska nu börja med bokstaven C. Så här ser koden ut för de två första bokstäverna:
Jag tänker att det blir väldigt många "onödiga" "drawPixel" om jag ska skriva för varje rad. Någon som har tips på hur jag skulle kunna tänka när jag skriver ut C?
Jag har löst den men markerar uppgiften ännu ej löst för att se om det finns något smidigare sätt att lösa detta på. Min kod till att skriva ut ett C är (no hate, väldigt simpelt...):
Du har säkert märkt att det är knepigt att skapa slingorna som ritar varje stor bokstav. Varje sådan slinga är unik för varje stor bokstav. Det gör att du får ett stort antal slingor och ett stort antal anrop till drawPixel(). Du har också ett stort antal så kallade "magic numbers", dvs nummer som är svåra att förstå vad de representerar och som är helt magiska för någon som försöker läsa koden. Som exempel:
if(i!=4&&i!=9&&i!=10)
Det finns smidigare sätt som gör det enklare att skapa de stora bokstäverna och undvika kodkopiering. Det viktigaste är att separera datamodellen från koden som visar den. Sök efter Model–view–controller på internet så kan du läsa mer om detta.
Istället för att ha unik kod som visar varje del av datamodellen (de stora bokstäverna) så skapar du en datamodell för samtliga stora bokstäver och skriver generell kod som visar varje del av datamodellen (varje stor bokstav).
Datamodellen kan skapas på olika sätt men här är ett exempel som gör modellen väldigt kompakt och gör att du kan se hur varje bokstav kommer att se ut vid visning. Datamodellen är så liten att den kan sparas i programmet.
Låt varje stor bokstav representeras av en 8x11 matris (som är bredd gånger höjd på de stora bokstäverna). En char i C kan hålla 8 bitar så det behövs endast 11 char för en stor bokstav. Ange värdet för varje char i binär form:
char bokstav[11] =
{ // A
0b0001000,
0b0010100,
0b0100010,
0b1000001,
0b1000001,
0b1111111,
0b1000001,
0b1000001,
0b1000001,
0b1000001,
0b1000001,
};
Man kan se hur ettorna bildar ett 'A', eller hur?
Skapa datamodellen genom att lägga in representationen av de stora bokstäverna i en vektor:
#define ALPHA_LENGTH 29
#define CHAR_HEIGHT 11char model[ALPHA_LENGTH][CHAR_HEIGHT] = {
{ // A
0b0001000,
0b0010100,
0b0100010,
0b1000001,
0b1000001,
0b1111111,
0b1000001,
0b1000001,
0b1000001,
0b1000001,
0b1000001,
},
{ // B
0b1111100,
0b1000010,
0b1000001,
0b1000001,
0b1000010,
0b1111100,
0b1000010,
0b1000001,
0b1000001,
0b1000010,
0b1111100,
},/* et cetera */
};
Nu syns ett 'B' också.
ALPHA_LENGTH anger hur många bokstäver modellen ska rymma (29 för det svenska alfabetet) och CHAR_HEIGHT anger höjden på varje bokstav (11 i detta fall). Dessa definitioner kan användas istället för "magic numbers" i koden. Det gör att koden blir lättare att läsa och ändra.
Pseudokoden för koden som använder datamodellen är:
Vilken bokstav ska visas ('A'-'Ö') och var ska den visas (x, y)?
Leta fram bokstavens representation i modellen.
Repetera för varje rad i modellen för bokstaven:
Repetera för varje kolumn i modellen för bokstaven:
Om biten i kolumnen är satt till 1:
Beräkna var pixeln ska visas (x+kolumn, y+rad).
Visa pixeln, dvs anropa drawPixel().
C-koden då? Ja, den kan ta en del tid att knåpa ihop (det tog en timme för mig) men går säkert snabbare än att skriva unik kod för varje bokstav. Detta kan till en början kännas tungt men jag lovar att detta är betydigt bättre sätt att göra det på. Om du ger dig på att implementera detta så är jag beredd att svara på frågor.
Vilken respons man får! Jag är mycket tacksam!
Ja, varsågod. Jag tycker programmering är roligt och tycker det är kul att hjälpa andra.
Om du provat koda mitt förslag och kört fast så skriv här så får du hjälp.