int

Assignments
Read the ‘overzicht’ document!
Aan
[email protected]
[email protected]
Onderwerp
V2CCPP1 x y
x = student nummer
y = nummer van de opgave, 1..12
Bijlage
De uitwerking.
Als de uitwerking meerdere file beslaat moet de bijlage een .zip file
zijn. Geen andere compressie formaten gebruiken!
Body
Geen eisen
W 2 L 1 sh 1
C lessons
Lesson
Subject
Week 1 lesson 1
Objects, names
Week 1 lesson 2
Statements, layout
Week 2 lesson 1
Functions, decomposition
Week 2 lesson 2
Lists, specification
Week 3 lesson 1
Memory, testing
Week 3 lesson 2
Fagan inspection



Book
The most important way to structure your program
The most important things to name
The most important things to reuse
W 2 L 1 sh 2
C function

Interface:





name
argument list
return type
Interface only  declaration int give_me_eight(
With body  definition (== implementation)
void );
int give_me_eight( void ){
return 8;
}


The name identifies the function: two visible functions
can not have the same name (!= C++)
The argument list must match the actual arguments
passed in each call (in number and type)
W 2 L 1 sh 3
Parameters and result

Formal parameters





are mentioned in the interface
Used in the body (implementation)
Actual parameters

int add( int a, int b ){
return a + b;
}
int x = add( a, 8 );
Is what you (the caller) supply when you can a function
Are (sort-of) assigned to the formal parameters
Result



Is what is after the executed ‘return’ statement
Return behaves as an assignment to an invisible variable.
Is the result of the function call
W 2 L 1 sh 4
Parameter passing – by value
Basic types are passed ‘by value’
void
c
i
f
p
}
g( char c, int i, float f, int *p ){
= 'a';
= 5;
= 10.0;
= NULL;
int main( void ){
char c = 'x';
int i = 0;
float f = 0.0;
int *p = &i;
printf( "%c %d %f %d \n", c, i, f, (int)p );
g( c, i, f, p );
printf( "%c %d %f %d \n", c, i, f, (int)p );
}
W 2 L 1 sh 5
Parameter passing - pointers
To change a basic type: pass a pointer to it
void g(
*c =
*i =
*f =
*p =
}
char *c, int *i, float *f, int **p ){
'a';
5;
10.0;
NULL;
int main( void ){
char c = 'x';
int i = 0;
float f = 0.0;
int *p = &i;
printf( "%c %d %f %d \n", c, i, f, (int)p );
g( &c, &i, &f, &p );
printf( "%c %d %f %d \n", c, i, f, (int)p );
}
W 2 L 1 sh 6
Parameter passing - arrays
Arrays are invisibly passed ‘by reference’ == ‘by address’
void f(
a[ 0
a[ 1
a[ 2
a[ 3
a[ 4
}
int
] =
] =
] =
] =
] =
a[ 5 ] ){
5;
4;
3;
2;
1;
int main( void ){
int a[ 5 ] = { 1, 2, 3, 4, 5 };
printf( "%d %d %d %d %d \n", a[0], a[1], a[2], a[3], a[4] );
f( a );
printf( "%d %d %d %d %d \n", a[0], a[1], a[2], a[3], a[4] );
}
W 2 L 1 sh 7
Parameter passing – array size
Array parameters can either be


Of a specific size
Without a specific size
Without a specific size, you will
need some other way to find
out how large the array is (or
you will create the next buffer
overrun exploit..)
void f( int a[ 5 ] ){
int i;
for( i = 0; i < 5; i++ ){
...
}
}
void f( int a[] ){
int i;
for( i = 0; i < ??; i++ ){
...
}
}
W 2 L 1 sh 8
Function pointers – pass ‘work’ around
#include <stdio.h>
typedef int (*int_filter)( int );
int add1( int x ){ return x + 1; }
int clip10( int x ){ return x > 10 ? 10 : x; }
int absolute( int x ){ return x > 0 ? x : -x; }
void apply_int_filter( int a[], int size, int_filter f ){
int i; for( i = 0; i < size; i++ ){
a[ i ] = f( a[ i ] );
}
}
void array_print( int a[], int size ){
int i; for( i = 0; i < size; i++ ){
printf( "%4d ", a[ i ] );
}
printf( "\n" );
}
W 2 L 1 sh 9
Function pointers – pass ‘work’ around
int main( void ){
#define a_size 7
int a[ a_size ] = { -1, -2, 0, 1, 2, 10, 100 };
array_print( a, a_size );
apply_int_filter( a, a_size, add1 );
array_print( a, a_size );
apply_int_filter( a, a_size, clip10 );
array_print( a, a_size );
apply_int_filter( a, a_size, absolute );
array_print( a, a_size );
system("PAUSE");
return 0;
}
W 2 L 1 sh 10
A simple NDS paint application
mkt.py info
libnds
graphics lib
Lcd lib ‘init’
poll the keys
read stylus
f = 60 Hz
#configure board
#configure emulator
ndsi
desmume
#include <nds.h>
#include <nds/touch.h>
#include "lcd.h"
int main( void ){
struct touchPosition position;
nintendo_screen lcd;
lcd.clear( colors::red );
for(;;){
scanKeys();
int held = keysHeld();
if( held & KEY_TOUCH ){
touchRead( & position );
lcd.pixel_write( position.px, position.py, colors::black );
}
swiWaitForVBlank();
}
return 0;
}
W 2 L 1 sh 11
Paint within an area
rectangle
check
function
show
paint
only when
within
#define
#define
#define
#define
rx0
ry0
rx1
ry1
10
10
200
180
int position_is_in_rectangle( int x, int y, int x0, int y0, int x1, int y1 ){
return( x > x0 && x < x1 && y > y0 && y < y1 );
}
int main( void ){
struct touchPosition position;
nintendo_screen lcd;
lcd.clear( colors::red );
lcd.rectangle_write( rx0, ry0, rx1, ry1 );
for(;;){
scanKeys();
int held = keysHeld();
if( held & KEY_TOUCH ){
touchRead( & position );
if( position_is_in_rectangle(
position.px, position.py, rx0, ry0, rx1, ry1
)){
lcd.pixel_write( position.px, position.py, colors::blue );
}
}
swiWaitForVBlank();
}
return 0;
}
W 2 L 1 sh 12
But we want more
The paint area is just one ‘object’ on the screen.
We want more, like changing the brush color.
Because (re)drawing and the action are
separated we must specify the coordinates
twice .
 Build a list of ‘active objects’.
W 2 L 1 sh 13
Paint - a list of objects
‘forward’
object
linked list of
objects
Create an
object
and
chain it.
typedef struct area_struct area;
typedef void ( *action )( int x, int y, area *a );
struct area_struct {
area *next;
int x0, y0, x1, y1;
action f;
};
area *first = NULL;
void area_add( int x0, int y0, int x1, int y1, color fill, action f ){
area *p = (area*) malloc( sizeof( area ));
p->x0 = x0;
p->x1 = x1;
p->y0 = y0;
p->y1 = y1;
p->f = f;
lcd.rectangle_write( x0, y0, x1, y1, colors::black, fill );
p->next = first;
first = p;
}
Q: this is not quality code. Why?
W 2 L 1 sh 14
Paint – create the list
Check,
maybe
excute
void execute( int x, int y ){
area *p;
for( p = first; p!= NULL; p = p->next ){
if( position_is_in_rectangle( x, y, p->x0, p->y0, p->x1, p->y1 )){
p->f( x, y, p );
}
}
}
global
color active_color = colors::blue;
draw-box
action
void paint( int x, int y, area *a ){
lcd.pixel_write( x, y, active_color );
}
void select_red( int x, int y, area *a ){
active_color = colors::red;
}
void select_green( int x, int y, area *a ){
active_color = colors::green;
}
void select_blue( int x, int y, area *a ){
active_color = colors::blue;
}
change-color
actions
W 2 L 1 sh 15
Paint - main
Create list
Execute
list
int main( void ){
struct touchPosition position;
lcd.clear( colors::yellow );
area_add( 10, 10, 200, 180, colors::white,
area_add( 210, 10, 220, 20, colors::red,
area_add( 210, 25, 220, 35, colors::green,
area_add( 210, 40, 220, 50, colors::blue,
for(;;){
scanKeys();
int held = keysHeld();
if( held & KEY_TOUCH ){
touchRead( & position );
execute( position.px, position.py );
}
swiWaitForVBlank();
}
return 0;
}
paint );
select_red );
select_green );
select_blue );
W 2 L 1 sh 16
IDE

Make sure you have copied or installed






devkitPro (in C:\devkitPro)
DeSuME (in C:\devkitPro\sim\DeSmuME)
Python (2.5, 26, 3.0, 3.1, etc)
PSPad
devkitPro.zip
get the week-2-1-paint.zip, unzip to a directory,
no spaces in the path name !!
Double-click Project.ppr
W 2 L 1 sh 17
IDE
Compile, link, build, run
simulator
W 2 L 1 sh 18
Assignment



Create an NDS GUI for the reversi code.
Use week-2-1-reversi.zip
Use you own reversi code
W 2 L 1 sh 19
Assignment - list
Field (0..99)
struct area_struct {
area *next;
int field;
int x0, y0, x1, y1;
action f;
};
void area_add( int field, int x0, int y0, int x1, int y1, action f ){
area *p = (area*) malloc( sizeof( area ));
p->x0 = x0;
p->x1 = x1;
p->y0 = y0;
p->y1 = y1;
p->field = field;
p->next = first;
p->f = f;
first = p;
}
W 2 L 1 sh 20
Assignment - main
int main( void ){
struct touchPosition position;
init_reversi();
redraw();
for(;;){
scanKeys();
int held = keysHeld();
if( held & KEY_TOUCH ){
touchRead( & position );
execute( position.px, position.py );
redraw();
}
swiWaitForVBlank();
}
return 0;
}
W 2 L 1 sh 21
Assignment – reversi GUI
nintendo_screen lcd;
int side_to_move = black;
board global_board;
int other_side( int x ){ return x == black ? white : black; }
color side_color( int side ){ return side == black ? colors::blue : colors :: red; }
void try_move( int x, int y, area * a ){ }
void redraw_square( area * a ){ }
void redraw( void ){ }
void init_reversi( void ){
int i, x, y;
const int width = 18;
reversi_board_init( global_board );
for( i = 0; i < 100; i++ ){
x = 5 + (( i / 10 ) * width );
y = 5 + (( i % 10 ) * width );
area_add( i, x, y, x + width, y + width, try_move );
}
}
W 2 L 1 sh 22
Assignment
Function
# Lines in my version
Remarks
try_move
8
If the move is allowed (for the current side-to-move) do it,
and update side_to_move.
redraw_square
26
(lots of folded lines)
Redraw the border around the square. Draw fill for
border, empty square. Draw the tile within an occupied
square.
redraw
12
Clear LCD
Redraw all squares (call redraw_square to do the work)
Redraw ‘side to move’ indicator
What if the current side-to-move has no legal moves?
W 2 L 1 sh 23