Untitled
unknown
plain_text
2 years ago
6.4 kB
6
Indexable
#include<unordered_map>
#include<string>
#include<cstring>
#include<list>
#define MAXL (10)
const int MAX_TYPE = 10001; // max N
const int MAX_SUBJECT = 21; // max subject
const int MAX_JOIN = 51; // max joint called
const int MAX_LEAVE = 51; // max leave called
using namespace std;
struct Card{
string Subject;
string Word;
int cnt_player;
int total;
int owner[MAX_JOIN];
};
Card pool_card[MAX_TYPE]; // idx = id
struct Player {
int score;
bool isPlaying;
int hold[MAX_TYPE];
};
Player pool_Player[MAX_JOIN]; // idx = id
int maxmax; // number of cards
int cnt_Subject = 0;
unordered_map<string, int> mapSubject; // subject | 1 - 20
list<int> my_store[21][26][27]; // subject(1-20) - begin1 - begin2
/*** API ***/
void init(int N, char mWordList[][MAXL + 1], char mSubjectList[][MAXL + 1]){
pool_card[0].cnt_player = 0;
pool_card[0].Word = "DEL";
maxmax = N;
mapSubject.clear();
// reset tree
for (int i = 0; i < 21; i++)
for (int j = 0; j < 26; j++)
for (int k = 0; k < 27; k++)
my_store[i][j][k].clear();
// reset map subject
cnt_Subject = 1;
for (int i = 1; i <= maxmax; i++){
pool_card[i].cnt_player = 0;
pool_card[i].Word = mWordList[i-1];
pool_card[i].Subject = mSubjectList[i-1];
for (int x = 1; x < MAX_JOIN; x++) pool_card[i].owner[x] = 0;
// update map Subject
string sub = pool_card[i].Subject;
auto iter = mapSubject.find(sub);
if (iter == mapSubject.end()){ // chua co
mapSubject[sub] = cnt_Subject;
cnt_Subject++;
}
}
// reset players
for (int i = 1; i < MAX_JOIN; i++){
pool_Player[i].isPlaying = false;
pool_Player[i].score = 0;
for (int j = 1; j <= maxmax; j++)
pool_Player[i].hold[j] = 0;
}
return;
}
void addCard(int mID, int idCard){
// update card
pool_card[idCard].total++;
pool_card[idCard].owner[mID]++;
if (pool_card[idCard].owner[mID] == 1){
pool_card[idCard].cnt_player++;
}
// update list;
if (pool_card[idCard].total == 1){ // neu chua co
int sub = mapSubject[pool_card[idCard].Subject];
int begin1 = pool_card[idCard].Word[0] - 'a';
int begin2 = pool_card[idCard].Word[1] - 'a';
my_store[sub][begin1][begin2].push_back(idCard);
my_store[sub][begin1][26].push_back(idCard);
}
}
void join(int mID, int M, int mCardList[]){
pool_Player[mID].score = 0;
pool_Player[mID].isPlaying = true;
for (int i = 0; i < M; i++){
pool_Player[mID].hold[mCardList[i]]++;
addCard(mID, mCardList[i]);
}
}
bool cmp (int idx1, int idx2){
if (pool_card[idx1].cnt_player == pool_card[idx2].cnt_player)
return pool_card[idx1].Word > pool_card[idx2].Word;
return pool_card[idx1].cnt_player > pool_card[idx2].cnt_player;
}
int cardSubmit[MAX_JOIN] = {0};
//int scoreInRound[MAX_TYPE] = {0};
unordered_map<int, int> scoreInRound;
int playRound(char mBeginStr[], char mSubject[]){
int res = 0;
for (int i = 1; i < MAX_JOIN; i++)
cardSubmit[i] = 0;
scoreInRound.clear();
list<int> candidate;
int sub = mapSubject[mSubject];
int begin1 = mBeginStr[0]-'a';
int begin2 = mBeginStr[1]-'a';
int len = strlen(mBeginStr);
if (len == 1) candidate = my_store[sub][begin1][26];
if (len == 2) candidate = my_store[sub][begin1][begin2];
if (candidate.empty())
return 0;
for (int i = 1; i < MAX_JOIN; i++){
if (!pool_Player[i].isPlaying) continue;
int okCandidate = 0;
for (auto it = candidate.begin(); it != candidate.end(); it++){
if (pool_Player[i].hold[*it] > 0 && cmp (*it, okCandidate) )
okCandidate = *it;
}
if (okCandidate != 0){
// danh dau la bai danh
if (pool_Player[i].hold[okCandidate] > 0){
cardSubmit[i] = okCandidate;
scoreInRound[okCandidate]++;
res += okCandidate;
}
}
}
for (int i = 1; i < MAX_JOIN; i++){
if (!pool_Player[i].isPlaying || cardSubmit[i] == 0) continue;
// update card
pool_card[cardSubmit[i]].owner[i]--;
pool_card[cardSubmit[i]].total--;
if (pool_card[cardSubmit[i]].owner[i] == 0) pool_card[cardSubmit[i]].cnt_player--;
// update player
pool_Player[i].hold[cardSubmit[i]]--;
// update list
if (pool_card[cardSubmit[i]].total == 0 && len == 1){
for (auto it = my_store[sub][begin1][26].begin(); it != my_store[sub][begin1][26].end(); ){
if (*it == cardSubmit[i]){
my_store[sub][begin1][26].erase(it);
it = my_store[sub][begin1][26].begin();
}else it++;
}
}
if (pool_card[cardSubmit[i]].total == 0 && len == 2){
for (auto it = my_store[sub][begin1][begin2].begin(); it != my_store[sub][begin1][begin2].end(); ){
if (*it == cardSubmit[i]) {
my_store[sub][begin1][begin2].erase(it);
it = my_store[sub][begin1][begin2].begin();
}else it++;
}
}
// update score
int temp = scoreInRound[cardSubmit[i]] - 1;
pool_Player[i].score += temp * temp;
}
return res;
}
void delCard(int mID, int idCard, int num){
// update card
pool_card[idCard].total -= num;
pool_card[idCard].owner[mID] -= num;
if (pool_card[idCard].owner[mID] == 0) pool_card[idCard].cnt_player--;
// update list
int sub = idCard;
int begin1 = pool_card[idCard].Word[0] - 'a';
int begin2 = pool_card[idCard].Word[1] - 'a';
if (pool_card[idCard].total == 0){
for (auto it = my_store[sub][begin1][begin2].begin(); it != my_store[sub][begin1][begin2].end(); ){
if (*it == idCard) {
my_store[sub][begin1][begin2].erase(it);
it = my_store[sub][begin1][begin2].begin();
}
else it++;
}
for (auto it = my_store[sub][begin1][26].begin(); it != my_store[sub][begin1][26].end(); it++){
if (*it == idCard) {
my_store[sub][begin1][begin2].erase(it);
my_store[sub][begin1][26].erase(it);
}
else it++;
}
}
}
int leave(int mID){ // call max 50
int res = pool_Player[mID].score;
pool_Player[mID].score = 0;
pool_Player[mID].isPlaying = false;
for (int i = 1; i <= maxmax; i++){
if (pool_Player[mID].hold[i] != 0){
delCard(mID, i, pool_Player[mID].hold[i]);
pool_Player[mID].hold[i] = 0;
}
}
return res;
}Editor is loading...
Leave a Comment