Interactive C
#use sony-ir.icb
#define OFFSET 111
#define LIGHT_VALUE 118
// Dark retuns a higher value than white.
int playing=0,s=0,signal=0,i=0,curir=0;
int notes[9]={0,880,932,1046,588,660,698,784,1174};
int LIGHT_VALUE,OFFSET;
int posx=0,posy=3,heading=0;
char song1[]="0D0B1A7A1D4D0D0B2A1A2B1B7D0D0B2A1A2D4D0D0B7A6A7B6B5B7B6C0C1A7A1D4D0D0B2A1A2B1B7D0D0B2A1A2D4D0D0B7A6A7B6B5B7B6F5A6A7F6A7A1B7B6B5B4D2D1L1A2A1A7A1P8D";
struct grid {
int pit;
int wumpus;
int gold;
int blank;
//int visited;
int visited2;
int path;
};
struct grid board[4][4] = { {{2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}},
{{2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}},
{{0, 0, 0, 1, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}},
{{0, 0, 0, 1, 1, 1}, {0, 0, 0, 1, 0, 0}, {2, 2, 2, 2, 0, 0}, {2, 2, 2, 2, 0, 0}} };
int y = 3,x=0;
int foundGold = 0,home=0,wumpusDead=0,foundWumpus=0,goldKnown=0;
void play(char item[]){
float a,b;
int size = _array_size(item);
playing = 1;
for(i=0; i < size-1; i+=2){
if(playing==0) return;
a= (float)(notes[item[i]-48]);
b= (float)(song1[i+1]-64)/8.;
if(a!=0.) tone(a,b);
else sleep(b);
sleep(.007);
}
playing = 0;
}
void fire(){
bk(0);
sleep(0.5);
fd(0);
sleep(0.25);
ao();
}
int getSignal(){
sony_init(1);
while(!stop_button()) {
curir = ir_data(0);
if(curir!=0) {
beep();
return curir;
}
sleep(0.1);
}
sony_init(0);
}
void forward(float t){
motor(1,50);
motor(3,50);
sleep(t);
ao();
}
void back(float t){
motor(1,-50);
motor(3,-50);
sleep(t);
ao();
}
void right(float t){ //turn right in place
motor(1,-50);
motor(3,50);
sleep(t);
ao();
}
void left(float t){ //turn left in place
motor(3,-50);
motor(1,50);
sleep(t);
ao();
}
void align(){
back(.25); //we hit a line back up a bit
motor(1,20); //slowly go forward
motor(3,20);
//essentially just a timer, wont turn off motors until either the left or right sensor sees white. Either one goes white it will quit.
while((analog(6)+OFFSET)>LIGHT_VALUE && (analog(4)+OFFSET)>LIGHT_VALUE){}
ao();
if((analog(6)+OFFSET)>LIGHT_VALUE){
motor(1,20);
motor(3,-20);
while((analog(6)+OFFSET)>LIGHT_VALUE){}
ao();
}
else if((analog(4)+OFFSET)>LIGHT_VALUE){
motor(1,-20);
motor(3,20);
while((analog(4)+OFFSET)>LIGHT_VALUE){}
ao();
}
}
//[0,0][0,1][0,2]
//[1,0][1,1][1,2]
//[2,0][2,1][2,2]
void goto(int y, int x){
//Make us face right
int moved =0;
//toward [0,3]
if(posx<x){
while(heading !=0){
left(.70);
heading--;
}
back(.75);
}
while(posx<x){
while((analog(6)+OFFSET)>LIGHT_VALUE && (analog(4)+OFFSET)>LIGHT_VALUE)
forward(.01);
align();
align();
forward(.2);
posx++;
moved =1;
}
if(moved==1){
forward(2.);//move();
moved=0;
}
//toward[3,0]
if(posy<y){
while(heading!=1){
right(.85);//turn_left
heading++;
}
back(.75);
}
while(posy<y){
while((analog(6)+OFFSET)>LIGHT_VALUE && (analog(4)+OFFSET)>LIGHT_VALUE)
forward(.01);
align();
align();
forward(.2);
posy++;
moved =2;
}
if(moved==2){
forward(2.);
moved =0;
}
//toward [0,1] from [0,3]
if(posx>x){
while(heading!=2){
right(.85); //turn_left();
heading++;
}
back(.75);
}
while(posx>x){
while((analog(6)+OFFSET)>LIGHT_VALUE && (analog(4)+OFFSET)>LIGHT_VALUE)
forward(.01);
align();
align();
forward(.2);
posx--;
moved=3;
}
if(moved==3){
forward(2.);
moved=0;
}
//toward [1,0] from [3,0]
if(posy>y){
while(heading!=3){
right(.85); //turn_left();
heading++;
}
back(.75);
}
while(posy>y){
while((analog(6)+OFFSET)>LIGHT_VALUE && (analog(4)+OFFSET)>LIGHT_VALUE)
forward(.01);
align();
align();
forward(.2);
posy--;
moved=4;
}
if(moved==4){
forward(2.);
moved=0;
}
}
void moveUp() {
board[y][x].visited2 = 1;
y -= 1;
goto(y,x);
//board[y][x].visited = 1;
board[y][x].path = 1;
}
void moveRight() {
board[y][x].visited2 = 1;
x += 1;
goto(y,x);
//board[y][x].visited = 1;
board[y][x].path = 1;
}
void moveDown() {
board[y][x].visited2 = 1;
y += 1;
goto(y,x);
//board[y][x].visited = 1;
board[y][x].path = 1;
}
void moveLeft() {
board[y][x].visited2 = 1;
x -= 1;
goto(y,x);
//board[y][x].visited = 1;
board[y][x].path = 1;
}
void goHome() {
if ((x > 0) && (board[y][x-1].visited2 == 1))
moveLeft();
else if ((y < 3) && (board[y+1][x].visited2 == 1))
moveDown();
else if ((x < 3) && (board[y][x+1].visited2 == 1))
moveRight();
else if ((y > 0) && (board[y-1][x].visited2 == 1))
moveUp();
}
void moveBack() {
board[y][x].path = 0;
if (((x > 0) && (board[y][x-1].path == 1))||((x > 0) && (board[y][x-1].visited2 == 1)))
moveLeft();
else if (((y < 3) && (board[y+1][x].path == 1))||((y < 3) && (board[y+1][x].visited2 == 1)))
moveDown();
else if (((x < 3) && (board[y][x+1].path == 1))||((x < 3) && (board[y][x+1].visited2 == 1)))
moveRight();
else if (((y > 0) && (board[y-1][x].path == 1))||((y > 0) && (board[y-1][x].visited2 == 1)))
moveUp();
}
void face(int y, int x){
if(posx<x){
while(heading !=0){
left(.70);
heading--;
}
back(.75);
}
else if(posy<y){
while(heading!=1){
right(.85);//turn_left
heading++;
}
back(.75);
}
else if(posx>x){
while(heading!=2){
right(.85); //turn_left();
heading++;
}
back(.75);
}
else if(posy>y){
while(heading!=3){
right(.85); //turn_left();
heading++;
}
back(.75);
}
}
void killWumpus(int yPos, int xPos) {
wumpusDead = 1;
board[yPos][xPos].blank = 1;
face(yPos,xPos);
right(1.5);
fire();
if(playing==0){
start_process(play(song1));
}
}
void updateWump(int a, int b) {
int i, j;
board[a][b].wumpus = 1;
board[a][b].pit = 0;
board[a][b].gold = 0;
board[a][b].blank = 0;
foundWumpus = 1;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (!((i == a) && (j == b)))
board[i][j].wumpus = 0;
}
}
}
void updateGold(int a, int b) {
int i, j;
board[a][b].gold = 1;
board[a][b].pit = 0;
board[a][b].wumpus = 0;
board[a][b].blank = 0;
goldKnown = 1;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (!((i == a) && (j == b)))
board[i][j].gold = 0;
}
}
}
void updateAdj() {
int i, j, a, b;
int numsurrounding;
if (signal == 128) { // nothing
if (y > 0) {
board[y-1][x].wumpus = 0;
board[y-1][x].gold = 0;
board[y-1][x].pit = 0;
board[y-1][x].blank = 1;
}
if (y < 3) {
board[y+1][x].wumpus = 0;
board[y+1][x].gold = 0;
board[y+1][x].pit = 0;
board[y+1][x].blank = 1;
}
if (x > 0) {
board[y][x-1].wumpus = 0;
board[y][x-1].gold = 0;
board[y][x-1].pit = 0;
board[y][x-1].blank = 1;
}
if (x < 3) {
board[y][x+1].wumpus = 0;
board[y][x+1].gold = 0;
board[y][x+1].pit = 0;
board[y][x+1].blank = 1;
}
}
else if (signal == 144) { // gold
board[y][x].gold = 0;
board[y][x].blank = 1;
foundGold = 1;
for (i = 0; i <= 3; i++) {
for (j = 0; j <= 3; j++) {
if (i != y && j != x) {
board[i][j].gold = 0;
}
}
}
}
else if (signal == 16) { // breeze
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].wumpus = 0;
board[y-1][x].gold = 0;
if (board[y-1][x].pit == 2)
board[y-1][x].pit = 3;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].wumpus = 0;
board[y+1][x].gold = 0;
if (board[y+1][x].pit == 2)
board[y+1][x].pit = 3;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].wumpus = 0;
board[y][x-1].gold = 0;
if (board[y][x-1].pit == 2)
board[y][x-1].pit = 3;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].wumpus = 0;
board[y][x+1].gold = 0;
if (board[y][x+1].pit == 2)
board[y][x+1].pit = 3;
}
}
else if (signal == 32) { // stench
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].pit = 0;
board[y-1][x].gold = 0;
if ((board[y-1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y-1][x].wumpus++;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].pit = 0;
board[y+1][x].gold = 0;
if ((board[y+1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y+1][x].wumpus++;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].pit = 0;
board[y][x-1].gold = 0;
if ((board[y][x-1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x-1].wumpus++;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].pit = 0;
board[y][x+1].gold = 0;
if ((board[y][x+1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x+1].wumpus++;
}
}
else if (signal == 64) { // glitter
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].wumpus = 0;
board[y-1][x].pit = 0;
if ((board[y-1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y-1][x].gold++;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].wumpus = 0;
board[y+1][x].pit = 0;
if ((board[y+1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y+1][x].gold++;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].wumpus = 0;
board[y][x-1].pit = 0;
if ((board[y][x-1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x-1].gold++;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].wumpus = 0;
board[y][x+1].pit = 0;
if ((board[y][x+1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x+1].gold++;
}
}
else if (signal == 48) { // stench & breeze
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].gold = 0;
if (board[y-1][x].pit == 2)
board[y-1][x].pit = 3;
if ((board[y-1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y-1][x].wumpus++;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].gold = 0;
if (board[y+1][x].pit == 2)
board[y+1][x].pit = 3;
if ((board[y+1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y+1][x].wumpus++;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].gold = 0;
if (board[y][x-1].pit == 2)
board[y][x-1].pit = 3;
if ((board[y][x-1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x-1].wumpus++;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].gold = 0;
if (board[y][x+1].pit == 2)
board[y][x+1].pit = 3;
if ((board[y][x+1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x+1].wumpus++;
}
}
else if (signal == 80) { // glitter & breeze
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].wumpus = 0;
if ((board[y-1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y-1][x].gold++;
if (board[y-1][x].pit == 2)
board[y-1][x].pit = 3;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].wumpus = 0;
if ((board[y+1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y+1][x].gold++;
if (board[y+1][x].pit == 2)
board[y+1][x].pit = 3;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].wumpus = 0;
if ((board[y][x-1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x-1].gold++;
if (board[y][x-1].pit == 2)
board[y][x-1].pit = 3;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].wumpus = 0;
if ((board[y][x+1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x+1].gold++;
if (board[y][x+1].pit == 2)
board[y][x+1].pit = 3;
}
}
else if (signal == 96) { // glitter & stench
if ((y > 0) && (board[y-1][x].blank != 1)) {
board[y-1][x].pit = 0;
if ((board[y-1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y-1][x].gold++;
if ((board[y-1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y-1][x].wumpus++;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
board[y+1][x].pit = 0;
if ((board[y+1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y+1][x].gold++;
if ((board[y+1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y+1][x].wumpus++;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
board[y][x-1].pit = 0;
if ((board[y][x-1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x-1].gold++;
if ((board[y][x-1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x-1].wumpus++;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
board[y][x+1].pit = 0;
if ((board[y][x+1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x+1].gold++;
if ((board[y][x+1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x+1].wumpus++;
}
}
else if (signal == 112) { // glitter & stench & breeze
if ((y > 0) && (board[y-1][x].blank != 1)) {
if ((board[y-1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y-1][x].gold++;
if ((board[y-1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y-1][x].wumpus++;
if (board[y-1][x].pit == 2)
board[y-1][x].pit = 3;
}
if ((y < 3) && (board[y+1][x].blank != 1)) {
if ((board[y+1][x].gold > 1) && (board[y][x].visited2 == 0))
board[y+1][x].gold++;
if ((board[y+1][x].wumpus > 1) && (board[y][x].visited2 == 0))
board[y+1][x].wumpus++;
if (board[y+1][x].pit == 2)
board[y+1][x].pit = 3;
}
if ((x > 0) && (board[y][x-1].blank != 1)) {
if ((board[y][x-1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x-1].gold++;
if ((board[y][x-1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x-1].wumpus++;
if (board[y][x-1].pit == 2)
board[y][x-1].pit = 3;
}
if ((x < 3) && (board[y][x+1].blank != 1)) {
if ((board[y][x+1].gold > 1) && (board[y][x].visited2 == 0))
board[y][x+1].gold++;
if ((board[y][x+1].wumpus > 1) && (board[y][x].visited2 == 0))
board[y][x+1].wumpus++;
if (board[y][x+1].pit == 2)
board[y][x+1].pit = 3;
}
}
// go through the board and mark all confirmed empty squares as confirmed blanks
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if ((board[i][j].gold == 0) && (board[i][j].wumpus == 0) && (board[i][j].pit == 0)) {
board[i][j].blank = 1;
}
}
}
// check all the squares to try to determine location of wumpus
if (!foundWumpus) {
for (a = 0; a < 4; a++) {
for (b = 0; b < 4; b++) {
if (board[a][b].wumpus > 3)
updateWump(a, b);
else if (board[a][b].wumpus == 3) {
numsurrounding = 0;
if (a > 0) {
if ((b > 0) && (board[a-1][b-1].wumpus > 2))
numsurrounding++;
if ((b < 3) && (board[a-1][b+1].wumpus > 2))
numsurrounding++;
}
if (a < 3) {
if ((b > 0) && (board[a+1][b-1].wumpus > 2))
numsurrounding++;
if ((b < 3) && (board[a+1][b+1].wumpus > 2))
numsurrounding++;
}
if ((numsurrounding == 0) || (numsurrounding > 2)) {
updateWump(a, b);
}
}
}
}
}
// check all the squares to try to determine location of gold
if (!goldKnown) {
for (a = 0; a < 4; a++) {
for (b = 0; b < 4; b++) {
if (board[a][b].gold > 3)
updateGold(a, b);
if (board[a][b].gold == 3) {
numsurrounding = 0;
if (a > 0) {
if ((b > 0) && (board[a-1][b-1].gold > 2))
numsurrounding++;
if ((b < 3) && (board[a-1][b+1].gold > 2))
numsurrounding++;
}
if (a < 3) {
if (b > 0) {
if (board[a+1][b-1].gold > 2)
numsurrounding++;
}
if (b < 3) {
if (board[a+1][b+1].gold > 2)
numsurrounding++;
}
}
if ((numsurrounding == 0) || (numsurrounding > 2)) {
updateGold(a, b);
}
}
}
}
}
}
void decide() {
// see if the squares might have gold and don't have a pit or wumpus
if ((y > 0) && ((board[y-1][x].gold > 0) && (board[y-1][x].wumpus == 0) && (board[y-1][x].pit == 0) && (board[y-1][x].visited2 == 0))) {
moveUp();
return;
}
if ((x < 3) && ((board[y][x+1].gold > 0) && (board[y][x+1].wumpus == 0) && (board[y][x+1].pit == 0) && (board[y][x+1].visited2 == 0))) {
moveRight();
return;
}
if ((y < 3) && ((board[y+1][x].gold > 0) && (board[y+1][x].wumpus == 0) && (board[y+1][x].pit == 0) && (board[y+1][x].visited2 == 0))) {
moveDown();
return;
}
if ((x > 0) && ((board[y][x-1].gold > 0) && (board[y][x-1].wumpus == 0) && (board[y][x-1].pit == 0) && (board[y][x-1].visited2 == 0))) {
moveLeft();
return;
}
// wumpus check
if (!wumpusDead) {
if ((y > 0) && (board[y-1][x].wumpus == 1)) {
killWumpus(y-1, x);
moveUp();
board[y][x].blank = 1;
return;
}
if ((x < 3) && (board[y][x+1].wumpus == 1)) {
killWumpus(y, x+1);
moveRight();
board[y][x].blank = 1;
return;
}
if ((y < 3) && (board[y+1][x].wumpus == 1)) {
killWumpus(y+1, x);
moveDown();
board[y][x].blank = 1;
return;
}
if ((x > 0) && (board[y][x-1].wumpus == 1)) {
killWumpus(y, x-1);
moveLeft();
board[y][x].blank = 1;
return;
}
}
// check for unexplored blank
if ((y > 0) && ((board[y-1][x].blank == 1) && (board[y-1][x].path == 0) && (board[y-1][x].visited2 == 0))) {
moveUp();
return;
}
if ((x < 3) && ((board[y][x+1].blank == 1) && (board[y][x+1].path == 0) && (board[y][x+1].visited2 == 0))) {
moveRight();
return;
}
if ((y < 3) && ((board[y+1][x].blank == 1) && (board[y+1][x].path == 0) && (board[y+1][x].visited2 == 0))) {
moveDown();
return;
}
if ((x > 0) && ((board[y][x-1].blank == 1) && (board[y][x-1].path == 0) && (board[y][x-1].visited2 == 0))) {
moveLeft();
return;
}
// otherwise, move back
moveBack();
}
void main(){
sony_init(1);
printf("\nReady to go\n");
while(!start_button()){}
while(!stop_button()){
moveUp();
signal = getSignal();
printf("cur: %d sig: %d",curir,signal);
curir = 0;
updateAdj();
while (!foundGold) {
decide();
printf("\nx= %d, y = %d\n", x, y);
signal = getSignal();
curir = 0;
updateAdj();
}
while (!home) {
goHome();
if (y == 3 && x == 0)
home = 1;
}
}
sony_init(0);
}
©2008-2009