國立屏東大學 資訊工程系 程式設計(一)
本次作業繳交將以資料夾的形式繳交,需要為每一題建立一個資料夾(資料夾名稱為該題題目前方之代號,第一題為「p1」,第二題為「p2」,餘以此類推),
繳交說明可參考作業3:連結
任何未依照正確繳交格式的檔案將以 0 分計算
本文使用「▴」及「↵」代表「空白字元」與「Enter 換行字元」,並且將使用者輸入的部份使用灰階方式顯示。
另外,題目的執行結果中,如果出現「(」、「)」、「:」、「;」、「.」與「,」等符號,皆為英文半形!
在日常生活當中,我們使用者所接觸的交互式介面通常不會限制使用者輸入訊息的長度,比如我們跟朋友用 LINE 聊天時,想打多少字就想打多少,而不會被系統提示說我們只能在每一次輸入的訊息中,只能打15或20個字等限制的情況。
因此,本題需請同學完成一個C語言程式,讓使用者輸入一個 長度不限 的字串,並將使用者輸入的訊息重新顯示給使用者看。
1. 同學在實作中可以嘗試先以 一個字元的方式 依序讀取輸入的內容,接著再檢查目前存放的空間是否已滿,如果滿了再將當前的空間增大。
2. 本次測試檔輸入的 內容長度 $\gt 1$
請參考以下 main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dynInput.h"
int main()
{
unsigned curr_cap = 1;
char* str = (char*)calloc(curr_cap, sizeof(char));
printf("Enter a string: ");
str = getInput(str, curr_cap);
printf("You entered:\n[%s]\n", str);
free(str);
return 0;
}
在本題,同學需要實作以下函式:
待同學實作完畢後,請函式定義與實作分別放入以下檔案後並繳交:
本題將以下 Makefile 進行批改:
all: main.c dynInput.o gcc main.c dynInput.o dynInput.o: dynInput.c gcc -c dynInput.c clean: rm -rf *.*~ *~ a.* *.o *.o~
請參考以下輸出範例:
[3:23▴user@ws▴p1]▴./a.out↵
Enter▴a▴string:▴May▴the▴Force▴be▴with▴you.↵
You▴entered:↵
[May▴the▴Force▴be▴with▴you.]↵
[3:23▴user@ws▴p1]
[3:23▴user@ws▴p1]▴./a.out↵
Enter▴a▴string:▴It’s▴over,▴Anakin.▴I▴have▴the▴high▴ground.↵
You▴entered:↵
[It’s▴over,▴Anakin.▴I▴have▴the▴high▴ground.]↵
[3:23▴user@ws▴p1]
[3:23▴user@ws▴p1]▴./a.out↵
Enter▴a▴string:▴THE▴ROPE,▴ALONG▴WITH▴THE▴STICK,▴ARE▴TWO▴OF▴MANKINDS▴OLDEST▴TOOLS.▴THE▴STICK▴TO▴KEEP▴THE▴BAD▴AWAY.▴THE▴ROPE▴USED▴TO▴BRING▴THE▴GOOD▴TOWARD▴US.▴THEY▴WERE▴OUR▴FIRST▴FRIENDS,▴OF▴OUR▴OWN▴INVENTION.▴WHEREVER▴THERE▴WERE▴PEOPLE,▴THERE▴WERE▴THE▴ROPE▴AND▴THE▴STICK.▴-▴from▴Kobo▴Abe▴"Nawa"↵
You▴entered:↵
[THE▴ROPE,▴ALONG▴WITH▴THE▴STICK,▴ARE▴TWO▴OF▴MANKINDS▴OLDEST▴TOOLS.▴THE▴STICK▴TO▴KEEP▴THE▴BAD▴AWAY.▴THE▴ROPE▴USED▴TO▴BRING▴THE▴GOOD▴TOWARD▴US.▴THEY▴WERE▴OUR▴FIRST▴FRIENDS,▴OF▴OUR▴OWN▴INVENTION.▴WHEREVER▴THERE▴WERE▴PEOPLE,▴THERE▴WERE▴THE▴ROPE▴AND▴THE▴STICK.▴-▴from▴Kobo▴Abe▴"Nawa"]↵
[3:23▴user@ws▴p1]
本題需請同學完成一個簡易泛型鍵值對 (Key-Value) 的管理器。該程式在執行後會提供一個輸入介面,讓使用者可以輸入以下操作:
為了實現以上操作,本體提供 標頭檔 define.h 來幫助同學完成本次作業,請參考以下內容:
#define MIN_VSTRING_LEN 2
#define GROWTH_RATE 2
#define SHRINK_RATE 0.5
typedef enum
{
INT,
DOUBLE,
STRING
} type_t;
typedef struct
{
type_t type;
char key[32];
void* value;
} kv_pair_t;
typedef struct
{
kv_pair_t* records;
unsigned size;
unsigned capacity;
} database;
在提供的標頭檔中,有以下兩個結構體:
從以上兩個結構體的內容可以看出本題所有操作都是建立在該兩個結構體上,因此本題需請同學完成以下函式:
在實作各項操作的函式時,請依照以下 左邊編號順序 進行錯誤判斷與處理(換行與排版請參考下方的輸出範例):
請參考下面 main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "database.h"
void dbList(const database* db)
{
printf("size(%u);cap(%u)\n", db->size, db->capacity);
if (db->size < 1)
{
printf("no data\n");
return;
}
for (unsigned i = 0; i < db->size; ++i)
{
printf("%u. ", i);
dbPrint(&db->records[i]);
printf("\n");
}
}
void dbInit(database* db)
{
db->records = (kv_pair_t*)malloc(2 * sizeof(kv_pair_t));
db->size = 0;
db->capacity = 2;
}
void dbHelp()
{
printf("usage:\n");
printf(" a)dd: add a new record\n");
printf(" d)elete: delete an record\n");
printf(" l)ist: list existing records\n");
printf(" q)uit: exit the program\n");
}
int main()
{
database db;
char choice = 0;
dbInit(&db);
printf("[type 'h' for help]\n");
do
{
printf("> ");
scanf(" %c", &choice);
switch (choice)
{
case 'a':
printf("\n");
dbAdd(&db);
printf("\n");
break;
case 'd':
printf("\n");
dbDelete(&db);
printf("\n");
break;
case 'l':
printf("\n");
dbList(&db);
printf("\n");
break;
case 'q':
dbFree(&db);
break;
case 'h':
printf("\n");
dbHelp();
printf("\n");
break;
default:
printf("\n");
printf("unknown choice\n");
printf("\n");
}
} while (choice != 'q');
dbFree(&db);
return 0;
}
待同學實作完畢後以下函式後:
請函式定義與實作分別放入以下檔案後並繳交:
本題將以下面的 Makefile 進行批改:
all: main.c database.o gcc main.c database.o database.o: database.c define.h gcc -c database.c clean: rm -rf *.*~ *~ a.* *.o *.o~
本題範例輸出如下:
[3:23▴user@ws▴p2]▴./a.out↵
[type▴'h'▴for▴help]↵
>▴h↵
↵
usage:↵
▴▴a)dd:▴add▴a▴new▴record↵
▴▴d)elete:▴delete▴an▴record↵
▴▴l)ist:▴list▴existing▴records↵
▴▴q)uit:▴exit▴the▴program↵
↵
>▴D↵
↵
unknown▴choice↵
↵
>▴d↵
↵
no▴data↵
↵
>▴l↵
↵
size(0);cap(2)↵
no▴data↵
↵
>▴q↵
[3:23▴user@ws▴p2]
[3:23▴user@ws▴p2]▴./a.out↵
[type▴'h'▴for▴help]↵
>▴a↵
↵
key:▴k▴1↵
invalid▴key↵
↵
>▴a↵
↵
key:▴k@1↵
invalid▴key↵
↵
>▴a↵
↵
key:▴k1↵
type▴(int,▴double,▴string):▴int↵
value:▴114514↵
↵
>▴l↵
↵
size(1);cap(2)↵
0.▴k1(int):▴[114514]↵
↵
>▴a↵
↵
key:▴k1↵
data▴already▴exists↵
↵
>▴a↵
↵
key:▴k2↵
type▴(int,▴double,▴string):▴float↵
unknown▴type↵
↵
>▴a↵
↵
key:▴k2↵
type▴(int,▴double,▴string):▴double↵
value:▴114514.114514↵
↵
>▴a↵
↵
key:▴k3↵
type▴(int,▴double,▴string):▴string↵
value:▴This▴is▴a▴test▴message▴that▴checks▴if▴dynamic▴input▴is▴working▴or▴not,▴if▴this▴message▴is▴not▴getting▴chopped▴off▴or▴displaying▴some▴visual▴errors,▴then▴IT▴WORKS▴:).↵
↵
>▴l↵
↵
size(3);cap(4)↵
0.▴k1(int):▴[114514]↵
1.▴k2(double):▴[114514.114514]↵
2.▴k3(string):▴[This▴is▴a▴test▴message▴that▴checks▴if▴dynamic▴input▴is▴working▴or▴not,▴if▴this▴message▴is▴not▴getting▴chopped▴off▴or▴displaying▴some▴visual▴errors,▴then▴IT▴WORKS▴:).]↵
↵
>▴q↵
[3:23▴user@ws▴p2]
[3:23▴user@ws▴p2]▴./a.out↵
[type▴'h'▴for▴help]↵
>▴a↵
↵
key:▴k1↵
type▴(int,▴double,▴string):▴int↵
value:▴114514↵
↵
>▴a↵
↵
key:▴k2↵
type▴(int,▴double,▴string):▴double↵
value:▴114514.114514↵
↵
>▴a↵
↵
key:▴k3↵
type▴(int,▴double,▴string):▴string↵
value:▴A▴test▴string▴that▴says▴“Hello▴World!”!↵
↵
>▴l↵
↵
size(3);cap(4)↵
0.▴k1(int):▴[114514]↵
1.▴k2(double):▴[114514.114514]↵
2.▴k3(string):▴[A▴test▴string▴that▴says▴“Hello▴World!”!]↵
↵
>▴d↵
↵
key:▴k▴1↵
data▴not▴found↵
↵
>▴d↵
↵
key:▴k2↵
↵
>▴l↵
↵
size(2);cap(2)↵
0.▴k1(int):▴[114514]↵
1.▴k3(string):▴[A▴test▴string▴that▴says▴“Hello▴World!”!]↵
↵
>▴d↵
↵
key:▴k1↵
↵
>▴l↵
↵
size(1);cap(1)↵
0.▴k3(string):▴[A▴test▴string▴that▴says▴“Hello▴World!”!]↵
↵
>▴q↵
[3:23▴user@ws▴p2]
經過了前幾週的作業對各種棋型(如活三死四等)的練習,同學已經具備了分析棋盤棋型的能力。本題為五子棋系列的綜合實踐題:將模擬真實比賽對弈環境,給定目前的棋盤狀態與落子顏色後, 請同學參考 五子棋 AI 程式競賽 - 進階篇權重分析的方法,找出棋盤上目前「最佳」的落子位置(最佳落子位置是由以下權重分析規則決定)。
權重分析規則:
.1.1.1.棋型為死三而不是洞三。可參考以下 main.c , define.h 的內容,讀取命令列參數與棋盤:
typedef enum {Black=49, White=48, None=0} Player;
#include <stdio.h>
#include <string.h>
#include "chess.h"
int main(int argc, char *argv[])
{
char chessboard[19][19];
Player player;
for(int i=0; i<19; i++)
for(int j=0; j<19; j++)
scanf(" %c", &chessboard[i][j]);
player = (strcmp(argv[1], "Black") == 0) ? Black : White;
findBestMove(chessboard, player);
}
本題的執行結果可參考如下:
[3:23 user@ws p3] ./a.out Black < testfile_1.cb↵
J,▴11↵
[3:23 user@ws p3] ./a.out White < testfile_2.cb↵
P,▴▴8↵
[3:23 user@ws p3] ./a.out Black < testfile_3.cb↵
N,▴15↵
[3:23 user@ws p3]
本題測試檔路徑:
/home/stu/public/c2026s/c.hw7/p3/testfile_1.cb/home/stu/public/c2026s/c.hw7/p3/testfile_2.cb/home/stu/public/c2026s/c.hw7/p3/testfile_3.cb在上個禮拜作業7的第6題中,同學已經完成亂數版的五子棋並上傳至平台進行初步參賽,而這次功課需要請同學將上一題實作的內容修改至自己的參賽版本,讓自己的五子棋具有一定棋力。
同學修改完後,請將修改完的五子棋重新上傳至平台:國立屏東大學資工系電腦五子棋 AI 競賽平台上(同樣使用gomoku2026為turnin code)。預計將會於2026/05/28於舉行第一次預賽,所有參賽同學的作品將進行兩兩對奕比試10場,其中5場先手,5場後手,勝負記點採用:勝者2分、平手1分、敗者0分(每局獲勝規則為:黑子先行,五子連線為勝利)。預賽完成後依最終每位參賽同學所得到的分數給定此次作業配分: