ホームページに戻る

ロボット

Qiitaでロボット開発中に、Qiitaでのログをコピーしています。

僕の作ったロボットのコードまとめ。

思考型ロボット

一号機。

#include <stdio.h>
#include <stdlib.h>
int getlp(int *p){
*p = rand()%2;
return 1;
}
void action(int *p){
if(*p==0){
printf("はらが減った。");
}
if(*p==1){
printf("はらは減っていない。");
}
}
int main(void){
int p;
while(getlp(&p)){
action(&p);
}
}

二号機。

#include <stdio.h>
#include <stdlib.h>
struct _obj {
int p;
int hara;
};
int getlp(struct _obj *obj){
obj->p = rand()%4;
return 1;
}
void action(struct _obj *obj){
if(obj->p==0){
printf("はらは");
if(obj->hara==0){printf("減った。");}
else{printf("減っていない。");}
}
if(obj->p==1){printf("楽しい。");}
if(obj->p==2){
printf("はらが減る");
obj->hara=0;
}
if(obj->p==3){
printf("おいしいごはんを食べた");
obj->hara=1;
}
}
int main(void){
struct _obj obj;
obj.hara=1;
while(getlp(&obj)){
action(&obj);
}
}

三号機。

#include <stdio.h>
#include <stdlib.h>
struct _obj {
int p;
int w;
int t;
};
int getlp(struct _obj *obj){
obj->p = rand()%5;
return 1;
}
void action(struct _obj *obj){
if(obj->p==0){
printf("ここは");
if(obj->w==1){
printf("日本です。");
}
if(obj->w==2){
printf("ドイツです。");
}
}
if(obj->p==1){
printf("日本にやってきました。");
obj->w=1;
}
if(obj->p==2){
printf("ドイツにやってきました。");
obj->w=2;
}
if(obj->p==3){
printf("想像力を使います。");
printf("りんごは赤い。");
obj->t=1;
}
if(obj->p==4){
printf("想像力を使います。");
printf("りんごは白い。");
obj->t=0;
}
if(obj->p==3||obj->p==4){
if(obj->t==1){
printf("正しい。");
}
else{
printf("間違っている。");
}
}
}
int main(void){
struct _obj obj;
obj.w=1;
obj.t=1;
while(getlp(&obj)){
action(&obj);
}
}

四号機。

#include <stdio.h>
#include <stdlib.h>

struct _obj {
  int o;
  int n;
};

void action(int* p, struct _obj *obj){
  if(*p==0){
    printf("[1] テレビは、つまらない\n");
  }
  if(*p==1){
    printf("[2] テレビは、面白い\n");
  }
  if(*p==2){
    printf("[3] パソコンは、つまらない\n");
  }
  if(*p==3){
    printf("[4] パソコンは、面白い\n");
  }
  if(*p==4){
    printf("[5] テレビやパソコンは、機械だ。\n");
  }
  if(*p==5){
    printf("[6] テレビやパソコンは、生き物ではない。\n");
  }
  if(*p==6){
    printf("[7] テレビって何なのだろう。\n");
  }
  if(*p==7){
    printf("[8] テレビとパソコンは好きだ。\n");
  }
  if(*p==8){
    printf("[9] テレビとパソコンは嫌いだ。\n");
  }
  if(*p==9){
    if(obj->n==0){
      printf("[10] 比較すると、テレビの方が普通だ。\n");
    }
    if(obj->n==1){
      printf("[11] 比較すると、パソコンの方が普通だ。\n");
    }
  }
  if(*p==10){
    if(obj->n==0){
      printf("[12] テレビよりパソコンの方が普通かな。\n");
      obj->n=1;
    }
    else if(obj->n==1){
      printf("[13] パソコンよりテレビの方が普通かな。\n");
      obj->n=0;
    }
  }
  if(*p==11){
    if(obj->o==0){
      printf("[14] リンゴが好きです。\n");
    }
    if(obj->o==1){
      printf("[15] みかんが好きです。\n");
    }
  }
  if(*p==12){
    if(obj->o==0){
      printf("[16] リンゴより、みかんが好きになりました。\n");
      obj->o=1;
    }
    else if(obj->o==1){
      printf("[17] みかんより、リンゴが好きになりました。\n");
      obj->o=0;
    }
  }
}

int main(void){
  int p;
  struct _obj obj;
  p=0;
  obj.o=0;
  obj.n=0;
  while(1){
    p=rand()%13;
    action(&p, &obj);
  }
}

このロボットは、改善点として、普通の人工知能を乗せる、思考を覚えて思い出す、マルチスレッドにして複数にする、などが考えられる。

推論型ロボット

僕は、何をすべきなのか、自分の力で考えるコンピュータを作るべきだと思う。

#include <stdio.h>

struct _obj {
  int p;
};

int check1 (struct _obj *obj) {
  if (obj->p == 0) {
    return 1;
  }
  return 0;
}
int check2 (struct _obj *obj) {
  if (obj->p == 1) {
    return 1;
  }
  return 0;
}
void action1 (struct _obj *obj) {
  printf("ここではアクション1をやります。\n");
}
void action2 (struct _obj *obj) {
  printf("ここではアクション2をやります。\n");
}
int main (void) {
  struct _obj obj;
  obj.p = 0;
  if (check1(&obj)){
    action1(&obj);
  }
  if (check2(&obj)){
    action2(&obj);
  }
}

2017.04.03

改良版ロボット

Qiitaでのやり取りの結果、今のロボットはこんなコードになっています。

#include <stdio.h>

struct _obj {
  int p;
};

int check1 (struct _obj *obj) {
  if (obj->p == 0) {
    return 1;
  }
  return 0;
}
int check2 (struct _obj *obj) {
  if (obj->p == 1) {
    return 1;
  }
  return 0;
}
void action1 (struct _obj *obj) {
  printf("ここではアクション1をやります。\n");
}
void action2 (struct _obj *obj) {
  printf("ここではアクション2をやります。\n");
}

struct brain {
  int (*check)(struct _obj *obj);
  void (*action)(struct _obj *obj);
} brain[] = {
  { check1, action1 },
  { check2, action2 },
  { NULL, NULL }
};

int main (void) {
  struct _obj obj = { .p = 0 };
  while(1){
    for (struct brain *b = brain; b->check; b++) {
      if (b->check(&obj)){
        b->action(&obj);
      }
    }
  }
}

コメント欄で改良版の原型を作ってくださったshiracamusさんに感謝します。

2017.04.12

改良版2

バグがあったので直しました。

#include <stdio.h>

struct _obj {
  int p;
};

int check1 (struct _obj *obj) {
  if (obj->p == 0) {
    return 1;
  }
  return 0;
}
int check2 (struct _obj *obj) {
  if (obj->p == 1) {
    return 1;
  }
  return 0;
}
void action1 (struct _obj *obj) {
  printf("ここではアクション1をやります。\n");
}
void action2 (struct _obj *obj) {
  printf("ここではアクション2をやります。\n");
}

void doing (struct _obj *obj) {
  struct brain {
    int (*check)(struct _obj *obj);
    void (*action)(struct _obj *obj);
  } brain[] = {
    { check1, action1 },
    { check2, action2 },
    { NULL, NULL }
  };
  struct brain *b;
  for (b = brain; b->check; b++) {
    if (b->check(obj)){
      b->action(obj);
    }
  }
}

int main (void) {
  struct _obj obj = { .p = 0 };
  struct _obj obj2 = { .p = 1 };
  while(1){
    doing(&obj);
    doing(&obj2);
  }
}

これではメモリリークしているのか、どうなのか分からないのですが、以下はそれを直したバージョンです。

#include <stdio.h>

struct _obj {
  int p;
};

int check1 (struct _obj *obj) {
  if (obj->p == 0) {
    return 1;
  }
  return 0;
}
int check2 (struct _obj *obj) {
  if (obj->p == 1) {
    return 1;
  }
  return 0;
}
void action1 (struct _obj *obj) {
  printf("ここではアクション1をやります。\n");
}
void action2 (struct _obj *obj) {
  printf("ここではアクション2をやります。\n");
}

struct brain {
  int (*check)(struct _obj *obj);
  void (*action)(struct _obj *obj);
} brain[] = {
  { check1, action1 },
  { check2, action2 },
  { NULL, NULL }
};

void doing (struct _obj *obj) {
  struct brain *b;
  for (b = brain; b->check; b++) {
    if (b->check(obj)){
      b->action(obj);
    }
  }
}

int main (void) {
  struct _obj obj = { .p = 0 };
  struct _obj obj2 = { .p = 1 };
  while(1){
    doing(&obj);
    doing(&obj2);
  }
}

これでメモリリークが直らないようであれば、カーネルの問題だと思います。(たぶん、メモリリークはしていません。自分の技術力のなさを反省します。)

2017.04.12

反応して同意するか否定するか判断するロボット

今度のロボットは、永遠に次の思考と主題に反応して、良いか悪いかを表示します。

#include <stdio.h>

struct _obj {
  int tf;
  int sbj;
};

void next_subject (struct _obj *obj){
  if (obj->sbj == 0){
    obj->tf = 0;
  }
  if (obj->sbj == 1){
    obj->tf = 1;
  }
}

void mind (struct _obj *obj){
  if (obj->tf == 0){
    printf("それはきっと正しい\n");
  }
  if (obj->tf == 1){
    printf("それはきっと間違っている\n");
  }
}

int main(void){
  struct _obj obj = { .tf = 0 };
  while(1){
    obj.sbj=0;
    next_subject(&obj);
    mind(&obj);
    obj.sbj=1;
    next_subject(&obj);
    mind(&obj);
  }
}

2017.04.28

反応・コメント

Qiitaでこんなコメントがありました。

「そもそも、sbj って何? tf って何? 0 って何? 1 って何?」

自分でも説明不足だったと思います。以下が、それに対する自分の回答です。

◇◇

sbjは主題です。tfは真偽値です。理解出来ないかもしれないです。ごめんなさい。

主題と真偽値は今のところ0と1になっていますが、これを追加して、たとえば主題2の時は正しい、3の時は間違っている、などとすることを想定しています。

主題と言うのは、数値になっているのは計算しやすくするためで、「猫は動物である」の時に正しい、「猫は植物である」の時に間違っている、などとすることを想定しています。

説明しないと、分からなかったかもしれないです。

◇◇

2017.04.29

凄い改良版ロボット

Qittaの方で、@shiracamusと言う方に物凄いロボットを作っていただきました。

嬉しいので、ここに投稿を引用させていただきます。

◇◇

0 とか 1 はマジックナンバーと呼ばれ、プログラムの可読性、保守性が低下します。

enum を使うようにしましょう。

変数名はできる限り省略せず、変数に格納される値の「意味」を表す名前にしましょう。

こんなことをしたいのかな? と考えてみた例を示しておきます。参考になれば幸いです。

#include <stdio.h>
#include <unistd.h>

typedef const char *String;
typedef enum { TRUE = (0 == 0), FALSE = (0 != 0) } Boolean;
typedef enum { CORRECT, WRONG, UNKNOWN } Judge;

typedef enum {
    NONE,
    ROBOT, CAT, DOG,
    MACHINE, HUMAN, ANIMAL, PLANT,
    PEACE, WAR
} Object;

typedef struct {
    Object object;
    Object type;
} Category;

Category categorize[] = {
    { ROBOT, MACHINE },
    { CAT, ANIMAL },
    { DOG, ANIMAL },
    { NONE, NONE }
};

Boolean Object_is(Object object, Object complement) {
    if (object == complement)
        return TRUE;
    for (Category *category = categorize; category->object != NONE; category++) {
        if (category->object == object &&
            category->type == complement)
            return TRUE;
    }
    return FALSE;
}

typedef struct {
    Object object;
    Judge judge;
} Mind;

typedef struct {
    String name;
    Object type;
    Mind *mind;
} Robot;

void Robot_areYou(Robot *robot, Object complement) {
    if (Object_is(robot->type, complement)) {
        printf("%s: はい、そうです\n", robot->name);
    } else {
        printf("%s: いいえ、違います\n", robot->name);
    }
}

void Robot_isThis(Robot *robot, Object object, Object complement) {
    if (Object_is(object, complement)) {
        printf("%s: はい、そうです\n", robot->name);
    } else {
        printf("%s: いいえ、違います\n", robot->name);
    }
}

void Robot_judge(Robot *robot, Object object) {
    for (Mind *mind = robot->mind; mind->object != NONE; mind++) {
        if (mind->object != object)
            continue;
        switch (mind->judge) {
        case CORRECT:
            printf("%s: それはきっと正しい\n", robot->name);
            return;
        case WRONG:
            printf("%s: それはきっと間違っている\n", robot->name);
            return;
        default:
            printf("%s: それは分かりません\n", robot->name);
            return;
        }
    }
    printf("%s: それは分かりません\n", robot->name);
}

int main(void) {

    Mind mind_of_robot[] = {
        { PEACE, CORRECT },
        { WAR, WRONG },
        { NONE, UNKNOWN },
    };
    Robot robot = {
        .name = "Mr.Robot",
        .type = ROBOT,
        .mind = mind_of_robot,
    };
    while(1){
        Robot_areYou(&robot, ROBOT);
        Robot_areYou(&robot, MACHINE);
        Robot_areYou(&robot, HUMAN);
        Robot_isThis(&robot, CAT, ANIMAL);
        Robot_isThis(&robot, CAT, PLANT);
        Robot_isThis(&robot, CAT, DOG);
        Robot_judge(&robot, PEACE);
        Robot_judge(&robot, WAR);
        sleep(1);
    }
}

実行結果

Mr.Robot: はい、そうです
Mr.Robot: はい、そうです
Mr.Robot: いいえ、違います
Mr.Robot: はい、そうです
Mr.Robot: いいえ、違います
Mr.Robot: いいえ、違います
Mr.Robot: それはきっと正しい
Mr.Robot: それはきっと間違っている

◇◇

(自分で書いたコードではありません。)

2017.04.29