質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

10回答

13671閲覧

トランプ52枚を使ったゲームを作りたい。シャッフルしたカードを、n人のプレイヤーにすべて配るプログラムを書きたいです。

carnage0216

総合スコア194

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

3クリップ

投稿2018/04/25 13:20

トランプ52枚を使ったゲームを作りたい。とのことですが52は数は多く私には難易度が高いため12枚にします。
プログラム全体はまだかけていませんが部分的なプログラムは何とか考えられています。
12枚のカード(すべてハート)なので
1人に配る場合余りなし
2人に配る場合余りなし
3人に配る場合余りなし
4人に配る場合余りなし
5人に配る場合あまり2枚になります。
そこで2枚の余りを5人にどう配るかで考えています。5人の内の1人に2枚配る場合と、5人の内の2人に一枚ずつ配る場合の二つがあります。
余りが2と言ところまでは作れました。問題はこの余り2を5人にどう渡すかです。

#include<stdio.h> int main() { int hito ; hito=5; int card ; card=12; printf("%d\n",card/hito); }

改良後がこちらです。A,B,C,D,Eの5人の手札と余りを表示するソースです。

#include<stdio.h> int main() { int hito; hito=5; int a; a=1; int b; b=1; int c; c=1; int d; d=1; int e; e=1; int A; int B; int C; int D; int E; int card ; card=12; A=card%(a+b+c+d+e); B=card%(a+b+c+d+e); C=card%(a+b+c+d+e); D=card%(a+b+c+d+e); E=card%(a+b+c+d+e); printf("Aのカードの枚数は%d\n",A); printf("Bのカードの枚数は%d\n",B); printf("Cのカードの枚数は%d\n",C); printf("Dのカードの枚数は%d\n",D); printf("Eのカードの枚数は%d\n",E); printf("カードの余りは%d\n",card/hito);

そのあと変数Aに余りの1か2のいずれかを加算させた際のプログラムを作りました。
変数Aに1か2が加算され、1の場合は1が余るので、その1がA以外のB~Dに入ります。
そこでランダム関数を使ってプログラムを書きました。途中までしかできなかったかというか詰まってしまい途中まで書いたようなプログラムになってしまいました。途中までではありますが実行は出来ます。しかし間違った結果が出ます。
もっとスマートに読みやすいように書くにはどうしたらよりでしょうか?
やはりif文などの分岐を使って長いコードを書くのでしょうか?
アドバイスと間違いを指摘していただければと思います。
またわがままながらできる限りプログラムの原型をとどめた状態で編集していただけると大変ありがたいです。どうかよろしくお願いいたします。
書いたソースはこちらです。

#include<stdio.h> #include <stdlib.h> #include <time.h> int main() { int hito; hito=5; int a; a=1; int b; b=1; int c; c=1; int d; d=1; int e; e=1; int A; int B; int C; int D; int E; int card ; card=12; A=card%(a+b+c+d+e); B=card%(a+b+c+d+e); C=card%(a+b+c+d+e); D=card%(a+b+c+d+e); E=card%(a+b+c+d+e); printf("Aのカードの枚数は%d\n",A); printf("Bのカードの枚数は%d\n",B); printf("Cのカードの枚数は%d\n",C); printf("Dのカードの枚数は%d\n",D); printf("Eのカードの枚数は%d\n",E); printf("カードの余りは%d\n",card/hito); srand(time(NULL)); int amari; amari = rand() % 2 + 1; printf("Aのカードの枚数は余りを足されて%d\n", A+amari); int x; amari-1; x=amari-1; printf("Bのカードの枚数は余りを足されて%d\n", B+x); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2018/04/25 13:36 編集

こういう仕様で作りたいって言うなら仕方ないんですが、「5人の内の1人に2枚配る場合と、5人の内の2人に一枚ずつ配る場合の二つがあります。」ってどっちかに決めないんですか?ディーラーの気分で「うーん今回はAさんに2枚!」とかやるゲームなんですか?
can110

2018/04/25 13:39

まずは「どうしたい」のかを決めて提示されないと回答は得られにくいかと思います。
guest

回答10

0

たぶん普通にトランプのカードを配る処理を作りたいだけなんだと思いますが、アルゴリズムの立て方がまずいので非常にややこしい話になっているのでしょう。

  1. カードをシャフルする。
  2. カードに1から順番に番号を振る。
  3. カードの順番を人数で整数除算して、余りを求める。
  4. 余りの数字がすなわちそのカードを手にするべき人の番号。

こういうことではないのでしょうか。ifとか出番はないんじゃないかと思いますね。

にっちもさっちもいかなくなったときは、思い切って方針を最初から考え直すことも大切だと思います。

投稿2018/04/25 13:49

KojiDoi

総合スコア13669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

A: 4, B: 2, C: 2, D:2, E: 2
でゲーム開始させられる可能性のあるAさんは親みたいなロールなのでしょうか?

問題点

配列

カードゲームのような
同列に扱っていい要素(プレイヤー,山札,手札)がたくさん出る場合
配列の知識が必須です。

逆に配列さえ理解していれば12枚だろうが52枚だろうが大差ありません。

アルゴリズム

それぞれに配る枚数を計算し、生成してまわる事も不可能ではありませんが
その場合、重複に気をつけなければいけません。
そして、重複をどうにかしようとすると結局山札として生成した後にシャッフルするのが楽になります。
というわけで、人の手でやるのと同様に
山札を用意して、シャッフルして、1枚ずつ配っていくのが楽です。
手札の枚数が分からんと手札領域を作れないというのなら、単純に**(山札枚数+人数-1)/人数**
で全員に最大1枚の余剰札が来ても大丈夫にしておいても実用上問題はないでしょう。

投稿2018/04/26 10:03

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/04/26 15:12

アルゴリズムの説明、どうもありがとうございます。 フォローありがとうございます。
guest

0

シャッフルしたカードを、n人のプレイヤーにすべて配るプログラムを書きたいです。

ごめんなさい先に書いちゃいました。

C++

1#include <iostream> 2#include <string> 3#include <array> 4#include <vector> 5#include <algorithm> 6#include <numeric> 7#include <random> 8 9std::string to_card(int n) { 10 static const std::string suit = "SHDC"; 11 static const std::string rank = "A23456789TJQK"; 12 return std::string(1,suit[n/13])+rank[n%13]; 13} 14 15int main() { 16 using namespace std; 17 18 // 52枚のcardからなるdeck 19 array<int,52> deck; 20 // card #0 ~ #51で埋める 21 iota(deck.begin(), deck.end(), 0); 22 // deckをシャッフル 23 shuffle(deck.begin(), deck.end(), mt19937(random_device()())); 24 25 // N人のplayer 26 const int N = 5; 27 vector<int> players[N]; 28 29 // deck内の各cardを playerに配る 30 int c = 0; 31 for ( int card : deck ) { 32 players[c].push_back(card); 33 if ( ++c == N ) c = 0; 34 } 35 36 // 各playerの手札を公開 37 for ( auto& hand : players ) { 38 cout << hand.size() << " cards: "; 39 for ( int id : hand ) { 40 cout << to_card(id) << ' '; 41 } 42 cout << endl; 43 } 44} 45 46/* 実行結果 4711 cards: C5 C8 H8 CQ C4 HA D8 C6 CA D2 S6 4811 cards: HK S5 S4 H7 S7 HT D9 S9 D4 H4 S8 4910 cards: S3 H2 CJ D6 DK H6 CT D3 H9 D5 5010 cards: HJ SA D7 DA C2 SJ HQ DJ CK H3 5110 cards: C7 S2 DT ST SQ C9 H5 DQ C3 SK 52*/

[追記] こっちの方がイケてるかな。

C++

1#include <iostream> // cout, endl 2#include <string> // string 3#include <vector> // vector 4#include <algorithm> // sort 5#include <numeric> // iota 6#include <random> // mt19937, random_device 7#include <utility> // pair, make_pair 8#include <cassert> // assert 9 10class card { 11private: 12 int id_; 13 explicit card(int id) : id_(id) { 14 assert( id >= 0 && id < 52 ); 15 } 16 17public: 18 card() = delete; 19 int suit() const { return id_ % 4; } 20 int rank() const { return id_ / 4; } 21 std::string suit_str() const { return std::string(1,"CDHS"[suit()]); } 22 std::string rank_str() const { return std::string(1,"A23456789TJQK"[rank()]); } 23 std::string str() const { return suit_str() + rank_str(); } 24 25 static card make(int id) { return card(id); } 26}; 27 28inline bool operator<(const card& a, const card& b) { 29 return std::make_pair(a.rank(),a.suit()) < std::make_pair(b.rank(),b.suit()); 30} 31 32inline std::ostream& operator<<(std::ostream& stream, const card& c) { 33 return stream << c.str(); 34} 35 36int main() { 37 using namespace std; 38 39 // N人のplayer 40 const int N = 5; 41 vector<vector<card>> players(N); 42 43 // 52枚のcardからなるdeck 44 vector<card> deck; 45 for ( int id = 0; id < 52; ++id ) { 46 deck.emplace_back(card::make(id)); 47 } 48 // deckをシャッフル 49 shuffle(deck.begin(), deck.end(), mt19937(random_device()())); 50 51 // deckが空になるまで、cardを各playerに配る 52 for ( int c = 0; !deck.empty(); ++c %= N ) { 53 players[c].emplace_back(deck.back()); 54 deck.pop_back(); 55 } 56 57 // 各playerに対し 58 for ( vector<card>& hand : players ) { 59 // 手札を(ソートして)公開 60 cout << hand.size() << " cards: "; 61 sort(hand.begin(), hand.end()); 62 for ( const card& c : hand ) { 63 cout << c << ' '; 64 } 65 cout << endl; 66 } 67}

投稿2018/04/26 10:01

編集2018/04/27 10:01
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/04/26 15:14

なぜ、そんなに早く、かつ美しいプログラムが書けるのですか? 頭の中をのぞいてみたいです。 解読するのに一週間くらいかかりますが、上達のため頑張ります!
episteme

2018/04/26 20:01

コメントでわかるけど、やりたいことを上から下へ順に並べるだけ。
KojiDoi

2018/04/27 04:40

皆さんいろんな角度から回答してますけど、煎じ詰めると指摘の本質は同じなんです。プログラミングに向いた手順というのがあるので、「自分が最初に思いついた手順」ばかり考えていてはダメ。少し角度を変えて課題を眺めてみることを覚えるのが「早く、かつ美しい」プログラムを書くには必須ですね。
episteme

2018/04/27 10:13

↑せやな。 呈示したコードも何度となくいぢくりまわした結果やし。 「コマケーことはいいんだよ!」から始めるのがコツかなーとか思う。
episteme

2018/04/27 10:34 編集

ひとつ気になるのは、各プレイヤーに配られるカードの枚数を"事前に"求めようとしてたのよね? それはナゼ? Cでは(vectorみたいな)可変長配列の実装が面倒だから?
carnage0216

2018/04/27 12:16

理由はCでの可変長配列の存在を知らなかった為です。 そのため、各プレイヤーにカードを渡す全ての場合を書こうとしました。 というのも、必ず1人は一枚以上カードを持たなくてはいけない為、プレイヤー最大で52人の場合まで書けば良いと考えたのですが♡♣️◇♠️の4種類も考慮しなければなりません。 今思うと全ての場合を書くほうが面倒ですが、それしか思いつきませんでした。
episteme

2018/04/27 12:25 編集

横着して struct player { struct card hand[52]; // 最大容量 int size; // 実際の枚数 ... }; でもよくね? # てかそんなんで悩むならC++で書いちゃえよ # vector<card> でイッパツやんか。
carnage0216

2018/04/27 13:55

確かにC++で書いたほうがいいかもしれません。 C言語初心者としていきなりC++ではなくⅭのみで書こうと思いました。
guest

0

最初のコードでいきなり間違えています。

余りが2と言ところまでは作れました。

c

1printf("%d\n",card/hito);

card / hitoで求められるのは一人あたりの配った枚数です。
余りを求めたいならcard % hitoが正解です。

今回、たまたま両方とも2だったので気付かなかったのでしょうか?
カードを10枚とか11枚にしてみれば間違いに気が付くと思います。

投稿2018/04/26 00:46

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/04/26 15:17

/だとあまりではなく商が出力されてしまうため、あまりがでる%だったのですね。 勘違いして/があまりがでる演算子だと思っていました。 まだまだ勉強不足です。 勉強します。 どうもありがとうございました。
dodox86

2018/04/26 23:09

/が商で、%が余りを求める演算子であるという話は、私のも含む、過去の質問回答で何度も出てきました。 いまだ理解していただけてなかったと言うことで、残念と言うほかありません。
guest

0

可能な限り原型を残しました。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4#define hito 5 5#define card 52 6 7char getName(int i) 8{ 9 return 'A' + i; 10} 11 12void swapInt(int *buffer, int a, int b) 13{ 14 int t = buffer[a]; 15 buffer[a] = buffer[b]; 16 buffer[b] = t; 17} 18 19void shuffleInt(int *buffer, int size) 20{ 21 srand(time(NULL)); 22 for (int i = 0; i < size; i++) 23 { 24 swapInt(buffer, i, rand() % size); 25 } 26} 27 28void dealRemainder(int remainders[], int size, int remainder) 29{ 30 for (int i = 0; i < size; i++) 31 { 32 remainders[i] = i < remainder ? 1 : 0; 33 } 34 shuffleInt(remainders, size); 35} 36 37int main() 38{ 39 int hands[hito]; 40 for (int i = 0; i < hito; i++) 41 { 42 hands[i] = card / hito; 43 printf("%cのカードの枚数は%d\n", getName(i), hands[i]); 44 } 45 int remainder = card % hito; 46 printf("カードの余りは%d\n", remainder); 47 int remainders[hito]; 48 dealRemainder(remainders, hito, remainder); 49 for (int i = 0; i < hito; i++) 50 { 51 if (remainders[i] == 0) 52 continue; 53 printf("%cのカードの枚数は余りを入れて%d\n", getName(i), hands[i] + remainders[i]); 54 } 55 return 0; 56}

投稿2018/04/25 14:44

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/04/25 15:40

どうもありがとうございます。真似させていただきます。
Zuishin

2018/04/25 15:45 編集

真似して何の意味があるんですか? if と for と配列とシャッフルのサンプルを出しましたので C 言語のリファレンスとにらめっこしてどう使うのかだけ知ってください。 カードの枚数だけを求めるプログラムなどトランプゲームを作る上で出番などありません。
carnage0216

2018/04/25 15:46

わかりました。使い方を覚えます。 手取り足取り、何から何までどうもありがとうございます。
guest

0

実際にカードを配るときのことを考えてください。自分を含めた5人で配ることを考えましょうか。

親(カードを配る人)が、自分、子1、子2、子3、子4 の順に、1枚ずつ配っていきませんか?
つまり、

  1. 渡す人の配列 player[5] を作る。とりあえず、player[0]は自分自身、以下[1]が子1、[2]が子2…とする
  2. n枚のカードをシャッフルして、配列 card[n] に並べる
  3. card[x] (ただし x は 0 ~ n-1 までのループを行う)を、

 x を5で割ったあまり(x % 5) の番号の人に渡す

ということをやっているのです。

この手順(アルゴリズム)さえ理解できれば、それをプログラミング言語で書き直すだけです。

投稿2018/04/26 01:36

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

なるべく質問者さんの意図に沿ったもののつもり

c

1#include <stdio.h> 2#include <stdbool.h> 3#include <stdint.h> 4#include <stdlib.h> 5#include <time.h> 6 7void swap(int8_t *b1, int8_t *b2){ 8 if(b1 == b2) return; 9 int8_t tmp = *b1; 10 *b1 = *b2; 11 *b2 = tmp; 12} 13 14// バイト単位でシャッフル 15void shuffle(int8_t *buf, size_t size){ 16 for(;size > 1;){ 17 int pos = rand() % size; 18 size--; 19 swap(buf+size, buf+pos); 20 } 21} 22// C言語にもconstexprください 23#define TRUMP_SUIT 4 24#define TRUMP_JOKER_ENABLE 0 25#define TRUMP_JOKER_AMOUNT 1 26#define TRUMP_MAX_RANK 13 27#define TRUMP_SUIT_OFFSET 6 28#define TRUMP_RANK_MASK 63 29const int TRUMPS = TRUMP_SUIT * TRUMP_MAX_RANK + TRUMP_JOKER_ENABLE * TRUMP_JOKER_AMOUNT; 30typedef uint8_t CARD; 31// xxyyyyyy 32// xx : suit 33// yyyyyy: rank(0 は joker) 34const char* SUIT_DISPLAY[] = { 35 "♤","♥","♣","♦" 36}; 37const char* RANK_DISPLAY[] ={ 38 "JK", 39 "A","2", "3", "4", "5", "6", "7", 40 "8","9","10", "J", "Q", "K" 41}; 42#define PLAYERS 5 43 44bool deck_build(CARD* deck, size_t size){ 45 if(size < TRUMPS) return false; 46 int i = 0; 47 for(int j = 0; j < TRUMP_SUIT; j++) 48 for(int k = 1; k <= TRUMP_MAX_RANK; k++) 49 deck[i++] = (j << TRUMP_SUIT_OFFSET) | k; 50 // ジョーカーの挿入 51 for(int j = 0; j < TRUMP_JOKER_AMOUNT; j++) 52 deck[i++] = (j << TRUMP_SUIT_OFFSET); 53 return true; 54} 55void display_cards(CARD* cards, size_t size){ 56 for(int i = 0; i < size; i++){ 57 int suit = cards[i] >> TRUMP_SUIT_OFFSET; 58 int rank = cards[i] & TRUMP_RANK_MASK; 59 if(rank == 0){ 60 printf(" %s", RANK_DISPLAY[rank]); 61 continue; 62 } 63 printf(" %s%s", SUIT_DISPLAY[suit],RANK_DISPLAY[rank]); 64 } 65 puts(""); 66} 67int main(){ 68 srand(time(NULL)); 69 CARD deck[TRUMPS]; 70 deck_build(deck, TRUMPS); 71 shuffle(deck, TRUMPS); 72 display_cards(deck, TRUMPS); 73 74 CARD* player_hand[PLAYERS]; 75 int player_hand_size[PLAYERS]={0}; 76 // プレイヤーの並び順 77 // めんどくさいからバイトシャッフル使うためにint8_t型 78 // 真面目にやる時はint型のshuffle関数を作る 79 int8_t player_order[PLAYERS]; 80 for(int8_t i = 0; i < PLAYERS;i++) player_order[i] = i; 81 shuffle(player_order, PLAYERS); 82 83 // それぞれの手札の枚数を求める 84 for(int i = 0, amari = TRUMPS % PLAYERS; i < PLAYERS; i++){ 85 player_hand_size[i] = TRUMPS / PLAYERS; 86 if(amari > player_order[i]) 87 player_hand_size[i]++; 88 printf("%c hand size = %d\n", 'A' + i, player_hand_size[i]); 89 } 90 91 // 配る 92 CARD *current = deck; 93 for(int i = 0; i < PLAYERS; i++){ 94 player_hand[i] = current; 95 current += player_hand_size[i]; 96 } 97 98 // 表示 99 for(int i = 0; i < PLAYERS; i++){ 100 printf("%c hand:", 'A' + i); 101 display_cards(player_hand[i],player_hand_size[i]); 102 } 103}

出力 =>

A hand size = 10 B hand size = 11 C hand size = 10 D hand size = 10 E hand size = 11 A hand: ♤Q ♤3 ♥2 ♥3 ♥K ♥5 ♤10 ♥9 ♣6 ♦10 B hand: ♦K ♥A ♥6 ♤4 ♦7 ♣J ♦3 ♣3 ♤J ♣5 ♦Q C hand: ♤K ♤2 ♦9 ♦4 ♦5 ♣7 ♣K ♥J ♣Q ♣9 D hand: ♦6 ♦J ♤A ♣10 ♥Q ♣2 ♤9 ♤7 ♥4 ♥7 E hand: ♣8 ♥8 ♤8 ♦A ♣A ♦2 ♥10 ♣4 ♤6 ♤5 ♦8

ラムダ式とconstexprがCにも欲しいですね

投稿2018/04/28 04:54

編集2018/04/28 08:29
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2018/04/28 06:59

こんなの眺めてると "Cがホントに初心者向きか?" って思っちゃうよねー...
carnage0216

2018/04/28 07:07

どうもありがとうございます。 解読するのに時間がかかりますが頑張ります。
carnage0216

2018/04/28 07:08

初心者向きだとC#とかですかね。名前しか知りませんが。
asm

2018/04/28 07:09

アルゴリズムとか関係ない部分で、ただただ面倒くさいですからね
tacsheaven

2018/04/28 07:37

昔から C を初心者向き、なんて書いてた書籍はなかったような? プログラミングの勉強なら PASCAL の方がよいとされてたこともありますし。(PASCAL は文法がかっちりしているので、C ほど奔放なコードがない) C の難関「ポインタ」にしても、素養がある(=CPUレベルでのメモリの使い方とかを知っている、当初のCの利用者層)人であれば、すんなり理解できる代物なのですし。
carnage0216

2018/04/28 08:16

asmさん、私の勘違いかもしれませんが、載せていただいたプログラムをgcc(Mingw)でコンパイルしたところ C:\MinGW\TRMPSAMPUL.c:6:11: error: unknown type name 'int8_t' void swap(int8_t *b1, int8_t *b2){ ^~~~~~ C:\MinGW\TRMPSAMPUL.c:6:23: error: unknown type name 'int8_t' void swap(int8_t *b1, int8_t *b2){ ^~~~~~ C:\MinGW\TRMPSAMPUL.c:14:14: error: unknown type name 'int8_t' void shuffle(int8_t *buf, size_t size){ ^~~~~~ C:\MinGW\TRMPSAMPUL.c:30:9: error: unknown type name 'uint8_t' typedef uint8_t CARD; ^~~~~~~ C:\MinGW\TRMPSAMPUL.c: In function 'main': C:\MinGW\TRMPSAMPUL.c:73:3: warning: implicit declaration of function 'shuffle' [-Wimplicit-function-declaration] shuffle(deck, TRUMPS); ^~~~~~~ C:\MinGW\TRMPSAMPUL.c:82:3: error: unknown type name 'int8_t' int8_t player_order[PLAYERS]; ^~~~~~ C:\MinGW\TRMPSAMPUL.c:83:7: error: unknown type name 'int8_t' for(int8_t i = 0; i < PLAYERS;i++) player_order[i] = i; ^~~~~~ とエラーが出ました。そこでヘッダファイル#include <stdint.h>を加えたところコンパイルできました。ちゃんと実行ファイルも得られました。 初心者の私が言えることではないのですが、#include <stdint.h>を付けたほうが良いのでしょうか?
asm

2018/04/28 08:23

付け忘れですね。gcc 7.3.0では動いたのでいらんのかと思ってました。 ありがとうございます
carnage0216

2018/04/28 08:35

私の勘違いでなくて良かったです。編集どうもありがとうございます。
guest

0

人と機械

目的が次のどちらなのか、をはっきりさせた方が良いと思います。

  • 「人」がトランプを配る(動作を模倣する)プログラムを作りたい
  • 「機械」がトランプを配るプログラムを作りたい

「人」と「機械」では配り方(アルゴリズム)が異なります。

スネ夫

C言語で作りたい、とのことですが、私には難易度が高い為、JavaScriptにします。

JavaScript

1'use strict'; 2function suneo (total, players, unit) { 3 const hands = Array(players).fill(0); 4 5 play: { 6 while (total) { 7 for (let i of hands.keys()) { 8 if (total <= unit) { 9 hands[i] += total; 10 break play; 11 } 12 13 total -= unit; 14 hands[i] += unit; 15 } 16 } 17 } 18 19 const length = hands.filter(hand => hand > 0).length; 20 21 if (length !== players) { 22 console.log('悪いな、のび太。このゲームは' + length + '人用なんだ。'); 23 } 24 25 return JSON.stringify(hands); // debug code 26} 27 28console.log(suneo(12, 5, 1)); 29console.log(suneo(12, 5, 2)); 30console.log(suneo(12, 5, 4));

スネ夫は優しくないので、余剰分も規定通りの枚数で配ります。
しずかちゃんなら公平に近い配り方をするでしょう。
あなたは誰派ですか。

Re: carnage0216 さん

投稿2018/04/25 15:05

think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

carnage0216

2018/04/25 15:43

ありがとうございます。しずかちゃんの考えはいいですが、スネ夫は「余剰分も規定通りの枚数で配る」ためスネ夫派ですね。
carnage0216

2018/04/25 15:44

私は「人」がトランプを配る(動作を模倣する)プログラムを作りたいです。
think49

2018/04/26 05:00 編集

52枚のトランプを5人に配る場合、機械なら「11+11+10+10+10」のように一度に配れます。 人間はそうはいきませんので、1枚ずつ、2枚ずつのように小分けして配ります。 carnage0216さんは「5人に配る場合あまり2枚」と端数以外を既に配りきった後を考えましたが、人間は小分けに配る生き物で、一度に配る枚数を指定して人間流になります。 人間は機械よりも効率が悪いのです。
carnage0216

2018/04/28 07:10

そうだったのですか。 どうもありがとうございます。 参考にさせていただきます。
guest

0

C

1int amari; 2 amari = card%hito - rand() % 2; 3 printf("Aのカードの枚数は余りを足されて%d\n", A+amari); 4int x; 5x=card%hito - amari; 6printf("Bのカードの枚数は余りを足されて%d\n", B+x);

投稿2018/04/25 15:19

編集2018/04/26 01:09
tekka

総合スコア514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自然に考えれば余った2枚は二人に一枚づつ配るのが適切だと思います。

この場合、カード枚数が52枚と決まっているので先に配列を用意しておくと良いです。この配列をシャッフルして一枚ずつplayerに配布するとかすれば確実です。余った二枚をどうするかという本題についてですが、これはダミーを使うという方法があります。最後に余った2枚に加えて無効カードを3枚用意して1枚ずつ配布し、これを無効分を除外するといった考え方です。

投稿2018/04/27 15:51

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問