Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
6.5 kB
0
Indexable
Never
#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];

	void reset(char mWordList[MAXL + 1], char mSubjectList[MAXL + 1]){
		Subject = mSubjectList;
		Word = mWordList;
		cnt_player = total = 0;
		for (int i = 0; i < MAX_JOIN; i++)
			owner[i] = 0;
	}
};
Card pool_card[MAX_TYPE];  // idx = id
  
struct Player {
    int score;
    bool isPlaying;
    int hold[MAX_TYPE];
	void reset(){
		score = 0;
		isPlaying = false;
		for (int i = 0; i < MAX_TYPE; i++)
			hold[i] = 0;
	}
};
Player pool_Player[MAX_JOIN]; // idx = id

int maxmax; // number of cards
  
int cnt_Subject;
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].Subject = "DEL";
	pool_card[0].Word = "DEL";
    maxmax = N;
	mapSubject.clear();
    // reset list
	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].reset(mWordList[i-1], mSubjectList[i-1]);
		
		// update map Subject
        auto iter = mapSubject.find(pool_card[i].Subject);
        if (iter == mapSubject.end()){ // chua co
            mapSubject[pool_card[i].Subject] = cnt_Subject;
            cnt_Subject++;
        }
    }
  //  // reset players
  //  for (int i = 1; i < MAX_JOIN; i++){
		//pool_Player[i].reset();
  //  }
    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].reset();

	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();
	/*for (int i = 1; i < MAX_TYPE; i++)
		scoreInRound[i] = 0;*/

	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 = mapSubject[pool_card[idCard].Subject];
    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(); it++){
			if (*it == idCard) {
				my_store[sub][begin1][begin2].erase(it);
				break;
			}
		}
		for (auto it = my_store[sub][begin1][26].begin(); it != my_store[sub][begin1][26].end(); it++){
			if (*it == idCard) {
				my_store[sub][begin1][26].erase(it);
				break;
			}		
		}
	}
}
 
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;
}
Leave a Comment