| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896 |
- package gamelogic
- import (
- "encoding/json"
- "fmt"
- "math/rand"
- "os"
- "path/filepath"
- "sort"
- "time"
- "bet24.com/servers/games/baloot/config"
- robotmanager "bet24.com/servers/insecureframe/robot"
- badge "bet24.com/servers/micros/badge/proto"
- cardlibrary "bet24.com/servers/micros/cardlibrary/proto"
- ladder "bet24.com/servers/micros/ladderservice/proto"
- task "bet24.com/servers/micros/task/proto"
- userservices "bet24.com/servers/micros/userservices/proto"
- waterpool "bet24.com/servers/micros/waterpool/proto"
- "bet24.com/servers/user"
- "github.com/google/uuid"
- excelize "github.com/xuri/excelize/v2"
- )
- func (ts *tablesink) checkAndStartGame() {
- if ts.gameScene.Phase != Phase_Free &&
- ts.gameScene.Phase != Phase_End &&
- ts.gameScene.Phase != Phase_GameEnd {
- return
- }
- // 查看是否所有人都ready
- readyCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- // 旁观不判断
- if userStatus <= user.UserStatus_Free ||
- userStatus == user.UserStatus_Watch {
- continue
- }
- if usr.GetUserStatus() != user.UserStatus_Ready && userStatus != user.UserStatus_Offline {
- ts.table.LogWithTableId("-----checkAndStartGame: chair[%d]: %d, status: %d", i, usr.GetUserId(), usr.GetUserStatus())
- return
- }
- readyCount++
- }
- ts.table.LogWithTableId("-----checkAndStartGame : %d ", readyCount)
- if readyCount >= CHAIR_COUNT {
- ts.startGame()
- }
- }
- func (ts *tablesink) checkUserReadyStatus(chair int) {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End && ts.gameScene.Phase != Phase_GameEnd {
- ts.table.LogWithTableId("tablesink.checkUserReadyStatus status not right %d", ts.gameScene.Phase)
- return
- }
- usr := ts.table.GetUserByChair(chair)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.checkUserReadyStatus user not exist %d", chair)
- return
- }
- if ts.gameScene.Phase == Phase_GameEnd {
- ts.table.SetUserReadyStatus(usr.GetUserIndex(), true)
- return
- }
- if !usr.IsRobot() {
- ts.table.LogWithTableId("tablesink.checkUserReadyStatus kicking [%d]: %d ", chair, usr.GetUserId())
- ts.table.UserWatch(usr.GetUserIndex())
- return
- }
- //桌上还有没有真人,有就准备,没有就踢走
- count := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- u := ts.table.GetUserByChair(i)
- if u == nil {
- continue
- }
- if u.IsRobot() {
- continue
- }
- if u.GetUserStatus() <= user.UserStatus_Free {
- continue
- }
- count++
- }
- if count >= 1 || (ts.roomInfo.Test && count >= 0) {
- ts.table.SetUserReadyStatus(usr.GetUserIndex(), true)
- } else {
- ts.table.LogWithTableId("tablesink.checkUserReadyStatus: %d ", usr.GetUserId())
- if usr.IsRobot() {
- //ts.table.UserWatch(usr.GetUserIndex())
- ts.table.KickUser(usr.GetUserIndex(), false)
- } else {
- ts.table.UserWatch(usr.GetUserIndex())
- }
- }
- }
- func (ts *tablesink) onPlayerFirstOutCard() {
- ts.gameScene.WhoseTurn = getPreviousChair(ts.gameScene.Banker)
- ts.gameScene.RoundIndex++
- ts.gameScene.LastTurn = -1
- ts.gameScene.Phase = Phase_Play
- ts.gameScene.PhaseIndex = 0
- ts.allPassCount = 0
- // 从初始化模拟场景数据
- ts.simulator = newSimulatorScene()
- ts.simulator.initData(ts.gameScene.TrumpType, ts.gameScene.FinalClub, ts.gameScene.BuyChair, ts.gameScene.BaseTimes,
- ts.gameScene.IsBO1, ts.gameScene.IsClose)
- delaySec := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.simulator.fakers[i].handCards = append(ts.simulator.fakers[i].handCards, ts.gameScene.Players[i].HandCards...)
- ts.simulator.fakers[i].actionProb = ts.gameScene.Players[i].robotActionProb
- cardList := make([]int, len(ts.gameScene.Players[i].HandCards))
- copy(cardList, ts.gameScene.Players[i].HandCards)
- ts.gameScene.Players[i].ProjectTips = ts.logic.getBestProject(cardList)
- if len(ts.gameScene.Players[i].ProjectTips) > 0 {
- if ts.gameScene.Players[i].ProjectTips[0] >= PROJECT_FIFTY && isMostOverKInHandCard(ts.gameScene.Players[i].HandCards, ts.gameScene.TrumpType) {
- ts.sendRobotChatAction(RobotChatAction_GoodHandCard, ts.gameScene.Players[i].userID, -1, delaySec)
- delaySec += 2500
- }
- }
- if isAllBelow10InHandCard(ts.gameScene.Players[i].HandCards) {
- ts.sendRobotChatAction(RobotChatAction_BadHandCard, ts.gameScene.Players[i].userID, -1, delaySec)
- delaySec += 2500
- }
- }
- ts.table.NotifySceneChanged(-1)
- ts.resetGameTimer()
- }
- func (ts *tablesink) isMeetTheStorageConditions() bool {
- if !ts.gameScene.isBuyChairWin() {
- return false
- }
- buyWinCardScore := 0
- playerWinCardScore := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, ts.gameScene.BuyChair) {
- buyWinCardScore += ts.gameScene.Players[i].winCardScore
- } else {
- playerWinCardScore += ts.gameScene.Players[i].winCardScore
- }
- }
- differ := buyWinCardScore - playerWinCardScore
- if differ < 30 {
- return false
- }
- percent := 0
- winScore := ts.gameScene.Players[ts.gameScene.BuyChair].winCardScore
- friendWinScore := ts.gameScene.Players[getFriendChair(ts.gameScene.BuyChair)].winCardScore
- percent = (winScore * 100) / (winScore + friendWinScore)
- return percent >= 60
- }
- func (ts *tablesink) isSatisfyTheCondition() bool {
- if ts.gameScene.FinalClub != Suit_Sun {
- return false
- }
- cardList := []int{}
- for i := 0; i < BUY_PHRSE_HOLD_CARD; i++ {
- cardList = append(cardList, ts.gameScene.Players[ts.gameScene.BuyChair].bakHandCards[i])
- }
- cardList = append(cardList, ts.gameScene.PublicCard)
- sortedCards := sortCards(cardList)
- // if haveFourA(cardList) {
- // return false
- // }
- maxCardNum := 0
- if ts.gameScene.FinalClub == Suit_Sun {
- for i := CardType_Diamond; i <= CardType_Spade; i++ {
- maxCardNum += getScoreCardNum(sortedCards[i], i, false)
- }
- if maxCardNum >= 4 {
- return true
- }
- }
- if ts.gameScene.FinalClub != Suit_Hokum {
- return false
- }
- if len(sortedCards[ts.gameScene.TrumpType]) < 3 {
- return false
- }
- if len(sortedCards[ts.gameScene.TrumpType]) >= 5 {
- return true
- }
- maxCardNum = 0
- trumpBigCardNum := getScoreCardNum(sortedCards[ts.gameScene.TrumpType], ts.gameScene.TrumpType, true)
- if len(sortedCards[ts.gameScene.TrumpType]) >= 3 && trumpBigCardNum >= 1 {
- for j := CardType_Diamond; j <= CardType_Spade; j++ {
- if ts.gameScene.TrumpType == j {
- continue
- }
- maxCardNum += getScoreCardNum(sortedCards[j], j, false)
- }
- if maxCardNum >= 1 {
- return true
- }
- }
- return false
- }
- func (ts *tablesink) statisRobotChatCount() {
- if !ts.roomInfo.Test {
- return
- }
- var f *excelize.File
- var err error
- sheetName := "Sheet1"
- // 先查看名为excelName的表格是否存在
- dirName := "./baloot_excel/robotchat"
- fileName := "baloot" + ts.uniqueId + ".xlsx"
- _, err1 := os.Stat(fileName)
- if err1 != nil {
- // 创建一个新的 Excel
- f = excelize.NewFile()
- // 在工作簿中添加一个名为 "Sheet1" 的工作表
- f.NewSheet(sheetName)
- // 设置列宽
- f.SetColWidth(sheetName, "A", "A", 5)
- f.SetColWidth(sheetName, "B", "B", 5)
- f.SetColWidth(sheetName, "C", "C", 5)
- f.SetColWidth(sheetName, "D", "D", 200)
- } else {
- // 打开一个现有的 Excel 文件
- f, err = excelize.OpenFile(fileName)
- if err != nil {
- return
- }
- }
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- // 获取已有数据的行数
- rows, err := f.GetRows(sheetName)
- if err != nil {
- return
- }
- rowIndex := len(rows)
- data := [][]string{}
- for i := 0; i < len(ts.gameScene.statics); i++ {
- str := []string{
- fmt.Sprintf("%d", ts.gameScene.ScoreToWin),
- fmt.Sprintf("%d", ts.gameScene.statics[i].round),
- fmt.Sprintf("%d", len(ts.gameScene.statics[i].action)),
- getRobotChatDesc(ts.gameScene.statics[i].action)}
- data = append(data, str)
- }
- for _, row := range data {
- for colIndex, col := range row {
- cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
- f.SetCellValue(sheetName, cellName, col)
- f.SetCellStyle(sheetName, cellName, cellName, style)
- }
- rowIndex++
- }
- f.SaveAs(filepath.Join(dirName, fileName))
- }
- func (ts *tablesink) statisticsScoreHistoryToExcel() {
- if !ts.roomInfo.Test {
- return
- }
- var f *excelize.File
- var err error
- sheetName := "Sheet1"
- // 先查看名为excelName的表格是否存在
- dirName := "./baloot_excel/scorehistory"
- fileName := "baloot" + ts.uniqueId + ".xlsx"
- _, err1 := os.Stat(fileName)
- if err1 != nil {
- // 创建一个新的 Excel
- f = excelize.NewFile()
- // 在工作簿中添加一个名为 "Sheet1" 的工作表
- f.NewSheet(sheetName)
- // 设置列宽
- f.SetColWidth(sheetName, "A", "A", 5)
- f.SetColWidth(sheetName, "B", "B", 100)
- } else {
- // 打开一个现有的 Excel 文件
- f, err = excelize.OpenFile(fileName)
- if err != nil {
- return
- }
- }
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- // 获取已有数据的行数
- rows, err := f.GetRows(sheetName)
- if err != nil {
- return
- }
- rowIndex := len(rows)
- data := [][]string{
- {fmt.Sprintf("%d", ts.gameScene.GameIndex), getScoreHistoryDesc(ts.gameScene.scoreHistory)},
- }
- for _, row := range data {
- for colIndex, col := range row {
- cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
- f.SetCellValue(sheetName, cellName, col)
- f.SetCellStyle(sheetName, cellName, cellName, style)
- }
- rowIndex++
- }
- f.SaveAs(filepath.Join(dirName, fileName))
- }
- func (ts *tablesink) genCardLibrary() {
- var f *excelize.File
- var err error
- sheetName := "Sheet1"
- // 先查看名为excelName的表格是否存在
- dirName := "./baloot_excel/cardlibrary"
- fileName := "baloot" + ts.uniqueId + ".xlsx"
- _, err1 := os.Stat(fileName)
- if err1 != nil {
- // 创建一个新的 Excel
- f = excelize.NewFile()
- // 在工作簿中添加一个名为 "Sheet1" 的工作表
- f.NewSheet(sheetName)
- // 设置列宽
- f.SetColWidth(sheetName, "A", "AI", 5)
- } else {
- // 打开一个现有的 Excel 文件
- f, err = excelize.OpenFile(fileName)
- if err != nil {
- return
- }
- }
- // 获取已有数据的行数
- rows, err := f.GetRows(sheetName)
- if err != nil {
- return
- }
- rowIndex := len(rows)
- // 追加数据到现有工作表
- data := [][]string{
- {fmt.Sprintf("%d", ts.gameScene.FirstActionChair), fmt.Sprintf("%d", ts.gameScene.BuyChair),
- fmt.Sprintf("%d", ts.logic.cards[0]), fmt.Sprintf("%d", ts.logic.cards[1]), fmt.Sprintf("%d", ts.logic.cards[2]),
- fmt.Sprintf("%d", ts.logic.cards[3]), fmt.Sprintf("%d", ts.logic.cards[4]), fmt.Sprintf("%d", ts.logic.cards[5]),
- fmt.Sprintf("%d", ts.logic.cards[6]), fmt.Sprintf("%d", ts.logic.cards[7]), fmt.Sprintf("%d", ts.logic.cards[8]),
- fmt.Sprintf("%d", ts.logic.cards[9]), fmt.Sprintf("%d", ts.logic.cards[10]), fmt.Sprintf("%d", ts.logic.cards[11]),
- fmt.Sprintf("%d", ts.logic.cards[12]), fmt.Sprintf("%d", ts.logic.cards[13]), fmt.Sprintf("%d", ts.logic.cards[14]),
- fmt.Sprintf("%d", ts.logic.cards[15]), fmt.Sprintf("%d", ts.logic.cards[16]), fmt.Sprintf("%d", ts.logic.cards[17]),
- fmt.Sprintf("%d", ts.logic.cards[18]), fmt.Sprintf("%d", ts.logic.cards[19]), fmt.Sprintf("%d", ts.logic.cards[20]),
- fmt.Sprintf("%d", ts.logic.cards[21]), fmt.Sprintf("%d", ts.logic.cards[22]), fmt.Sprintf("%d", ts.logic.cards[23]),
- fmt.Sprintf("%d", ts.logic.cards[24]), fmt.Sprintf("%d", ts.logic.cards[25]), fmt.Sprintf("%d", ts.logic.cards[26]),
- fmt.Sprintf("%d", ts.logic.cards[27]), fmt.Sprintf("%d", ts.logic.cards[28]), fmt.Sprintf("%d", ts.logic.cards[29]),
- fmt.Sprintf("%d", ts.logic.cards[30]), fmt.Sprintf("%d", ts.logic.cards[31]),
- fmt.Sprintf("%d", ts.gameScene.currentRoundDoubling)},
- }
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- for _, row := range data {
- for colIndex, col := range row {
- cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
- f.SetCellValue(sheetName, cellName, col)
- f.SetCellStyle(sheetName, cellName, cellName, style)
- }
- rowIndex++
- }
- // 保存到Excel文件中
- f.SaveAs(filepath.Join(dirName, fileName))
- }
- func (ts *tablesink) haveSmallProject() bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if len(ts.gameScene.Players[i].Projects) == 0 {
- continue
- }
- for j := 0; j < len(ts.gameScene.Players[i].Projects); j++ {
- if ts.gameScene.Players[i].bakProjects[j].Type == PROJECT_FOURHUNDRED {
- return false
- }
- if isBothInclude9J(ts.gameScene.Players[i].bakProjects[j].Cards) {
- return false
- }
- }
- return true
- }
- return false
- }
- func (ts *tablesink) statisticsRobotAction() {
- if !ts.roomInfo.Test {
- return
- }
- var f *excelize.File
- var err error
- sheetName := "Sheet1"
- // 先查看名为excelName的表格是否存在
- dirName := "./baloot_excel/robotaction"
- fileName := "baloot" + ts.uniqueId + ".xlsx"
- _, err1 := os.Stat(fileName)
- if err1 != nil {
- // 创建一个新的 Excel
- f = excelize.NewFile()
- // 在工作簿中添加一个名为 "Sheet1" 的工作表
- f.NewSheet(sheetName)
- // 设置列宽
- f.SetColWidth(sheetName, "A", "D", 10)
- } else {
- // 打开一个现有的 Excel 文件
- f, err = excelize.OpenFile(fileName)
- if err != nil {
- return
- }
- }
- // 获取已有数据的行数
- rows, err := f.GetRows(sheetName)
- if err != nil {
- return
- }
- rowIndex := len(rows)
- // 追加数据到现有工作表
- data := [][]string{}
- perStr := []string{}
- perStr = append(perStr, fmt.Sprintf("%d", ts.gameScene.FinalClub))
- for i := 0; i < CHAIR_COUNT; i++ {
- str := ts.getRobotTypeAction(i)
- perStr = append(perStr, str)
- }
- data = append(data, perStr)
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- for _, row := range data {
- for colIndex, col := range row {
- cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
- f.SetCellValue(sheetName, cellName, col)
- f.SetCellStyle(sheetName, cellName, cellName, style)
- }
- rowIndex++
- }
- // 保存到Excel文件中
- e := f.SaveAs(filepath.Join(dirName, fileName))
- if e != nil {
- ts.importDataToExcel()
- }
- }
- func (ts *tablesink) getRobotTypeAction(chairId int) string {
- if !ts.gameScene.Players[chairId].isRobot {
- return fmt.Sprintf("%d", 40)
- }
- if ts.gameScene.isBuyChairWin() {
- if isSameTeam(ts.gameScene.BuyChair, chairId) {
- return fmt.Sprintf("%d", ts.gameScene.Players[chairId].robotType*10+1)
- }
- return fmt.Sprintf("%d", ts.gameScene.Players[chairId].robotType*10)
- }
- if isSameTeam(ts.gameScene.BuyChair, chairId) {
- return fmt.Sprintf("%d", ts.gameScene.Players[chairId].robotType*10)
- }
- return fmt.Sprintf("%d", ts.gameScene.Players[chairId].robotType*10+1)
- }
- func (ts *tablesink) importDataToExcel() {
- if !ts.roomInfo.Test || !ts.roomInfo.IsDoublingMode {
- return
- }
- if !ts.isMeetTheStorageConditions() {
- return
- }
- if !ts.isSatisfyTheCondition() {
- return
- }
- if !ts.haveSmallProject() {
- return
- }
- ts.genCardLibrary()
- var f *excelize.File
- var err error
- sheetName := "Sheet1"
- // 先查看名为excelName的表格是否存在
- dirName := "./baloot_excel/cardlibrarydesc"
- fileName := "baloot" + ts.uniqueId + ".xlsx"
- _, err1 := os.Stat(fileName)
- if err1 != nil {
- // 创建一个新的 Excel
- f = excelize.NewFile()
- // 在工作簿中添加一个名为 "Sheet1" 的工作表
- f.NewSheet(sheetName)
- // 设置列宽
- f.SetColWidth(sheetName, "A", "A", 72)
- f.SetColWidth(sheetName, "B", "E", 40)
- f.SetColWidth(sheetName, "F", "F", 18)
- f.SetColWidth(sheetName, "G", "G", 15)
- f.SetColWidth(sheetName, "H", "H", 10)
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- f.SetCellStyle(sheetName, "A1", "H1", style)
- // 设置工作表的单元格值
- f.SetCellValue(sheetName, "A1", "[公共牌], [买牌玩家], [模式], [加倍倍数], [主牌花色], [BO1], [开关], [首出玩家], [买牌阶段]")
- f.SetCellValue(sheetName, "B1", "0号椅子玩家[全部手牌][剩余三张牌]")
- f.SetCellValue(sheetName, "C1", "1号椅子玩家[全部手牌][剩余三张牌]")
- f.SetCellValue(sheetName, "D1", "2号椅子玩家[全部手牌][剩余三张牌]")
- f.SetCellValue(sheetName, "E1", "3号椅子玩家[全部手牌][剩余三张牌]")
- f.SetCellValue(sheetName, "F1", "[0号, 1号, 2号, 3号]")
- f.SetCellValue(sheetName, "G1", "[0号队: 1号队]")
- f.SetCellValue(sheetName, "H1", "加倍倍数")
- } else {
- // 打开一个现有的 Excel 文件
- f, err = excelize.OpenFile(fileName)
- if err != nil {
- return
- }
- }
- // 获取已有数据的行数
- rows, err := f.GetRows(sheetName)
- if err != nil {
- return
- }
- rowIndex := len(rows)
- // 追加数据到现有工作表
- data := [][]string{
- {fmt.Sprintf("[%s], [%d], [%s], [%d], [%d], [%v], [%v], [%d], [%s]", getCardHex(ts.gameScene.PublicCard),
- ts.gameScene.BuyChair, getSuitDesc(ts.gameScene.FinalClub), ts.gameScene.BaseTimes,
- ts.gameScene.TrumpType, ts.gameScene.IsBO1, ts.gameScene.IsClose, ts.gameScene.FirstActionChair,
- getPhaseDesc(ts.gameScene.buyPhase)),
- getCardsHex(ts.gameScene.Players[0].bakHandCards) + getCardsHex(ts.gameScene.Players[0].LeftSendCards),
- getCardsHex(ts.gameScene.Players[1].bakHandCards) + getCardsHex(ts.gameScene.Players[1].LeftSendCards),
- getCardsHex(ts.gameScene.Players[2].bakHandCards) + getCardsHex(ts.gameScene.Players[2].LeftSendCards),
- getCardsHex(ts.gameScene.Players[3].bakHandCards) + getCardsHex(ts.gameScene.Players[3].LeftSendCards),
- fmt.Sprintf("[%d, %d, %d, %d]", ts.gameScene.Players[0].winCardScore, ts.gameScene.Players[1].winCardScore,
- ts.gameScene.Players[2].winCardScore, ts.gameScene.Players[3].winCardScore),
- fmt.Sprintf("[%d : %d]", ts.gameScene.Players[0].TotalChangeScore, ts.gameScene.Players[1].TotalChangeScore),
- fmt.Sprintf("%d", ts.gameScene.currentRoundDoubling)},
- }
- bigChair := 0
- bigScore := -1
- for i := 0; i < CHAIR_COUNT; i++ {
- if ts.gameScene.Players[i].winCardScore > bigScore {
- bigChair = i
- bigScore = ts.gameScene.Players[i].winCardScore
- }
- }
- // 设置对齐方式
- // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
- // 垂直对齐方式 center top justify distributed
- style, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- },
- })
- style1, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "center",
- Vertical: "center",
- }, Fill: excelize.Fill{
- Type: "pattern", // gradient 渐变色 pattern 填充图案
- Pattern: 1,
- Color: []string{"#FFFF00"},
- Shading: 1, // 类型是 gradient 使用 0-5 横向(每种颜色横向分布) 纵向 对角向上 对角向下 有外向内 由内向外
- },
- })
- for _, row := range data {
- for colIndex, col := range row {
- cellName, _ := excelize.CoordinatesToCellName(colIndex+1, rowIndex+1)
- f.SetCellValue(sheetName, cellName, col)
- if (bigChair + 1) == colIndex {
- f.SetCellStyle(sheetName, cellName, cellName, style1)
- } else {
- f.SetCellStyle(sheetName, cellName, cellName, style)
- }
- }
- rowIndex++
- }
- // 保存到Excel文件中
- f.SaveAs(filepath.Join(dirName, fileName))
- }
- func (ts *tablesink) dealGameTimeOut() {
- if ts.gameScene.Phase == Phase_End {
- return
- }
- switch ts.gameScene.Phase {
- case Phase_Start:
- ts.dealGamePlay()
- return
- case Phase_GameEnd:
- isSurrenderFinish := ts.surrenderInfo.isSurrenderEnd()
- if ts.gameScene.nextGame(isSurrenderFinish) {
- // 比赛场流程特殊处理
- if ts.table.GetOwner() == -1 && config.Server.IsLadderRoom == 0 {
- ts.gameScene.Phase = Phase_Free
- ts.table.NotifySceneChanged(-1)
- ts.table.SetTimer(TIMER_GAME, 3000)
- } else {
- ts.gameStart()
- diff := ts.gameScene.Players[0].TotalScore - ts.gameScene.Players[1].TotalScore
- win := 0
- if diff <= -80 || diff >= 80 {
- if diff >= 80 {
- win = 1
- }
- start := rand.Intn(4)
- for i := 0; i < CHAIR_COUNT; i++ {
- chairId := (start + i) % CHAIR_COUNT
- if !isSameTeam(chairId, win) && ts.gameScene.Players[chairId].isRobot {
- ts.sendRobotChatAction(RobotChatAction_LoseOverEighty, ts.gameScene.Players[chairId].userID, -1, 0)
- break
- }
- }
- }
- }
- } else {
- if isSurrenderFinish {
- ts.enterSurrenderEndPhase()
- } else {
- ts.enterEndPhase()
- }
- }
- return
- case Phase_Correct:
- ts.onTimerCorrectStart()
- return
- case Phase_Free:
- ts.gameStart()
- return
- case Phase_ChooseTrump:
- if !isValidChair(ts.gameScene.WhoseTurn) {
- ts.table.LogWithTableId("tablesink.dealGameTimeOut invalid whoseturn")
- return
- }
- if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
- }
- cardList := make([]int, len(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards))
- copy(cardList, ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards)
- cardList = append(cardList, ts.gameScene.PublicCard)
- t := getBestTrumpType(cardList, ts.gameScene.PublicCard)
- ts.dealChooseTrump(t)
- return
- case Phase_Reshuffle:
- for i := 0; i < CHAIR_COUNT; i++ {
- if ts.gameScene.Players[i].ReshuffleAction == Reshuffle_None && ts.gameScene.Players[i].CanDoReshuffle {
- if !ts.gameScene.Players[i].isRobot {
- ts.gameScene.Players[i].AutoOut = true
- }
- ts.dealReshuffle(i, Reshuffle_Pass)
- }
- }
- return
- case Phase_Double:
- for i := 0; i < CHAIR_COUNT; i++ {
- action := ts.gameScene.Players[i].getAutoBuyAction()
- if action != Action_Buy_Invaild && ts.gameScene.Players[i].canAction() {
- ts.gameScene.Players[i].AutoOut = true
- ts.dealDouble(i, action)
- }
- }
- return
- case Phase_Play:
- if !isValidChair(ts.gameScene.WhoseTurn) {
- ts.table.LogWithTableId("tablesink.dealGameTimeOut invalid whoseturn")
- return
- }
- projects := []int{}
- if len(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards) == 1 {
- ts.dealOutCard(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards[0], projects)
- return
- }
- if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
- }
- if ts.gameScene.Players[ts.gameScene.WhoseTurn].CanGawah {
- ts.dealGawah()
- return
- }
- outCard := CARD_COUNT
- if len(ts.gameScene.Players[ts.gameScene.WhoseTurn].BigCards) > 0 {
- outCard = ts.gameScene.Players[ts.gameScene.WhoseTurn].BigCards[0]
- } else {
- outCard = ts.logic.worstCard(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards, ts.gameScene.RoundType)
- }
- ts.dealOutCard(outCard, projects)
- return
- case Phase_FirstBuy:
- fallthrough
- case Phase_SecondBuy:
- if ts.gameScene.WhoseTurn != -1 {
- action := ts.gameScene.Players[ts.gameScene.WhoseTurn].getAutoBuyAction()
- if action != Action_Buy_Invaild && ts.gameScene.Players[ts.gameScene.WhoseTurn].canAction() {
- if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
- }
- ts.dealBuy(ts.gameScene.WhoseTurn, action)
- }
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- action := ts.gameScene.Players[i].getAutoBuyAction()
- if action != Action_Buy_Invaild && ts.gameScene.Players[i].canAction() {
- if !ts.gameScene.Players[i].isRobot {
- ts.gameScene.Players[i].AutoOut = true
- }
- ts.dealBuy(i, action)
- }
- }
- }
- return
- case Phase_CloseOpen:
- if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
- }
- ts.dealCloseOrOpen(Action_Buy_Open)
- return
- }
- ts.table.LogWithTableId("tablesink.dealGameTimeOut unreachable")
- }
- func (ts *tablesink) dealGamePlay() {
- ts.table.LogWithTableId("------dealGamePlay -----")
- ts.gameScene.Phase = Phase_FirstBuy
- ts.gameScene.PhaseIndex = 0
- for i := 0; i < CHAIR_COUNT; i++ {
- u := ts.table.GetUserByChair(i)
- if u == nil {
- continue
- }
- buyList := []int{}
- if i == ts.gameScene.WhoseTurn {
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Hokum, Action_Buy_Sun)
- }
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- ts.table.NotifySceneChanged(-1)
- ts.resetGameTimer()
- }
- func (ts *tablesink) startGame() {
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- if ts.canStartGame(true) {
- delayTime := 1500
- // 比赛场特殊处理
- if ts.table.GetOwner() == -1 {
- delayTime = 2000
- usr := ts.table.GetUserByChair(0)
- if usr.GetSetCount() == 1 {
- delayTime = 5000
- }
- } else if ts.table.GetOwner() > 0 {
- ts.table.NotifySceneChanged(-1)
- delayTime = 3000
- }
- ts.table.SetTimer(TIMER_START_GAME, delayTime)
- }
- }
- func (ts *tablesink) canStartGame(needCost bool) bool {
- count := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- break
- }
- userStatus := usr.GetUserStatus()
- if userStatus != user.UserStatus_Ready && userStatus != user.UserStatus_Offline {
- ts.table.LogWithTableId("ts.startGame chair[%d] userStatue = %d", i, userStatus)
- break
- }
- if !needCost {
- count++
- continue
- }
- userGold := ts.table.GetUserChipOrGoldByUser(usr)
- if userGold < ts.roomInfo.MinGold || (ts.roomInfo.MaxGold > 0 && userGold > ts.roomInfo.MaxGold) {
- ts.table.LogWithTableId("tablesink.startGame %d 金币不足,站起", usr.GetUserId(),userGold,ts.roomInfo.MinGold,ts.roomInfo.MaxGold)
- if usr.IsRobot() {
- go ts.table.KickUser(usr.GetUserIndex(), false)
- } else {
- go ts.table.UserWatch(usr.GetUserIndex())
- }
- break
- }
- // 先投注
- ok, _ := ts.writeScore(usr.GetUserId(), -ts.roomInfo.BaseScore, 0, 0, ScoreType_Bet, ts.roomInfo.RoomName, usr.IsRobot())
- if !ok {
- break
- }
- ts.gameScene.Players[i].initData(usr.GetUserId(), userGold, 0)
- ts.gameScene.Players[i].IsValid = true
- ts.gameScene.Players[i].userID = usr.GetUserId()
- ts.gameScene.Players[i].bet = ts.roomInfo.BaseScore
- ts.gameScene.Players[i].isRobot = usr.IsRobot()
- count++
- }
- if count < CHAIR_COUNT {
- ts.table.LogWithTableId("游戏开始,用户不足")
- if !needCost {
- return false
- }
- ts.gameScene.Phase = Phase_End
- ts.gameScene.PhaseIndex = 0
- // 分数还原
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- if ts.gameScene.Players[i].bet > 0 {
- ts.writeScore(ts.gameScene.Players[i].userID, ts.gameScene.Players[i].bet, 0, 0,
- ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
- }
- }
- if ts.table.IsPrivate() {
- ts.table.PrivateRoomSetWinners([]int{})
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- return false
- }
- return true
- }
- func (ts *tablesink) checkNeedControlPlayer() int {
- if !ts.roomInfo.IsOpenCardLibrary {
- return waterpool.PoolControl_Normal
- }
- if ts.gameScene.getUserCount() != 1 {
- return waterpool.PoolControl_Normal
- }
- controlType := waterpool.PoolControl_Normal
- gameType := waterpool.GameType_Normal
- if ts.roomInfo.IsDoublingMode {
- gameType = waterpool.GameType_Doubling
- }
- if ts.roomInfo.IsCorrectionMode {
- gameType = waterpool.GameType_Correct
- }
- isMatch := false
- if ts.table.GetOwner() == -1 {
- isMatch = true
- }
- baseScore := ts.roomInfo.BaseScore
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil || usr.IsRobot() {
- continue
- }
- if isMatch {
- baseScore = usr.GetBaseScore()
- }
- userId := usr.GetUserId()
- poolType, _ := waterpool.GetUserPoolType(userId, GAMEID, gameType, baseScore, usr.GetUserGold(), isMatch)
- if poolType == waterpool.PoolControl_Normal {
- continue
- }
- ts.gameScene.Players[i].isControl = true
- ts.gameScene.Players[i].controlType = poolType
- poolValue := waterpool.GetUserWaterPool(userId)
- if poolValue < 0 {
- poolValue = -poolValue
- }
- ts.gameScene.Players[i].controlDoubling = poolValue / baseScore / 2
- if ts.gameScene.Players[i].controlDoubling > MAX_DOUBLING_LIMIT {
- ts.gameScene.Players[i].controlDoubling = MAX_DOUBLING_LIMIT
- }
- r := 6 + rand.Intn(4)
- ts.gameScene.Players[i].averageDoubling = ts.gameScene.Players[i].controlDoubling / r
- if ts.gameScene.ScoreToWin == -1 {
- ts.gameScene.Players[i].averageDoubling = ts.gameScene.Players[i].controlDoubling
- }
- controlType = poolType
- }
- return controlType
- }
- func (ts *tablesink) checkNeedControlRobot() {
- if !ts.roomInfo.IsOpenCardLibrary {
- return
- }
- controlRobot := ts.gameScene.getControlRobot()
- if !isValidChair(controlRobot) {
- return
- }
- controlType := waterpool.GetInventoryType(GAMEID, ts.roomInfo.RoomName)
- if controlType > waterpool.PoolControl_Normal {
- ts.gameScene.Players[controlRobot].controlType = controlType
- ts.gameScene.Players[controlRobot].isControl = true
- }
- }
- func (ts *tablesink) isPlayerEnterChasing(chairId int) bool {
- if !ts.gameScene.Players[chairId].isControl {
- return false
- }
- if ts.gameScene.Players[chairId].controlType == waterpool.PoolControl_Lose &&
- ts.gameScene.Players[chairId].TotalScore > ts.gameScene.Players[getNextChair(chairId)].TotalScore {
- return true
- }
- if ts.gameScene.Players[chairId].controlType == waterpool.PoolControl_Win &&
- ts.gameScene.Players[chairId].TotalScore < ts.gameScene.Players[getNextChair(chairId)].TotalScore {
- return true
- }
- return false
- }
- func (ts *tablesink) isEnterWindUp() bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if ts.gameScene.Players[i].TotalScore >= WINDUP_SCORE {
- return true
- }
- }
- return false
- }
- func (ts *tablesink) getControlChair() (int, int, bool) {
- controlChair := -1
- realControlChair := -1
- if !ts.roomInfo.IsOpenCardLibrary {
- return controlChair, realControlChair, false
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- if !ts.gameScene.Players[i].isControl {
- continue
- }
- isNeedControl := false
- if !ts.roomInfo.IsDoublingMode {
- if ts.gameScene.GameIndex == 0 {
- isNeedControl = true
- } else {
- if ts.isPlayerEnterChasing(i) {
- isNeedControl = true
- }
- if ts.isEnterWindUp() {
- isNeedControl = true
- }
- }
- } else {
- isNeedControl = true
- }
- if !isNeedControl {
- continue
- }
- controType := ts.gameScene.Players[i].controlType
- if controType == waterpool.PoolControl_Win {
- controlChair = i
- } else {
- r := rand.Intn(10000)
- if r%2 == 1 {
- controlChair = getNextChair(i)
- } else {
- controlChair = getPreviousChair(i)
- }
- }
- realControlChair = i
- }
- return controlChair, realControlChair, false
- }
- func (ts *tablesink) getDoubling(controlChair int) int {
- if !isValidChair(controlChair) || !ts.roomInfo.IsDoublingMode {
- return -1
- }
- controlDoubling := ts.gameScene.Players[controlChair].controlDoubling
- if controlDoubling <= 0 {
- return controlDoubling
- }
- leftDoubling := 0
- if ts.gameScene.Players[controlChair].controlType == waterpool.PoolControl_Win {
- leftDoubling = controlDoubling - ts.gameScene.Players[controlChair].getPlayerCurrentTotalDoublings()
- } else {
- leftDoubling = controlDoubling - ts.gameScene.Players[getNextChair(controlChair)].getPlayerCurrentTotalDoublings()
- }
- if leftDoubling < ts.gameScene.Players[controlChair].averageDoubling {
- return 0
- }
- return ts.gameScene.Players[controlChair].averageDoubling
- }
- func (ts *tablesink) gameStart() {
- // 发牌
- controlChair, realControlChair, bNewUser := ts.getControlChair()
- doubling := ts.getDoubling(realControlChair)
- newChairId := -1
- if ts.roomInfo.RoomID == 0 && !ts.table.IsPrivate() {
- bNewUser = true
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- if !usr.IsRobot() {
- newChairId = i
- break
- }
- }
- }
- if bNewUser {
- controlChair = newChairId
- }
- ts.logic.shuffle(ts.roomInfo.Test, controlChair, ts.gameScene.FirstActionChair, doubling, bNewUser)
- if bNewUser || ts.roomInfo.IsOpenCardLibrary {
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- if userStatus <= user.UserStatus_Free ||
- userStatus == user.UserStatus_Watch {
- continue
- }
- ts.gameScene.Players[i].HandCards = ts.logic.getNormalCards()
- ts.gameScene.Players[i].bakHandCards = append(ts.gameScene.Players[i].bakHandCards, ts.gameScene.Players[i].HandCards...)
- }
- } else {
- var list []weightInfo
- for i := 0; i < CHAIR_COUNT; i++ {
- value := cardlibrary.GetUserCardLibraryrWeightValue(ts.gameScene.Players[i].userID)
- if ts.gameScene.Players[i].isRobot {
- value = 0
- }
- list = append(list, weightInfo{
- chair: i,
- weight: value,
- })
- }
- sort.Slice(list, func(i, j int) bool {
- return list[i].weight > list[j].weight
- })
- for i := 0; i < len(list); i++ {
- usr := ts.table.GetUserByChair(list[i].chair)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- if userStatus <= user.UserStatus_Free ||
- userStatus == user.UserStatus_Watch {
- continue
- }
- ts.gameScene.Players[list[i].chair].HandCards = ts.logic.getNormalCardsInControl(ts.gameScene.Players[list[i].chair].userID)
- ts.gameScene.Players[list[i].chair].bakHandCards = append(ts.gameScene.Players[list[i].chair].bakHandCards, ts.gameScene.Players[list[i].chair].HandCards...)
- }
- }
- ts.gameScene.PublicCard = ts.logic.getOneCard()
- ts.gameScene.Phase = Phase_Start
- ts.gameScene.PhaseIndex = 0
- ts.gameScene.LastTurn = -1
- ts.gameScene.Index++
- if ts.roomInfo.IsDoublingMode && getCardValue(ts.gameScene.PublicCard) == CardValueJ {
- ts.table.SetTimer(TIMER_GAME, SEC_START)
- } else {
- ts.table.SetTimer(TIMER_GAME, 2000)
- }
- ts.table.LogWithTableId("tablesink.gameStart[%d]", ts.table.GetTableID())
- if ts.gameScene.GameIndex == 0 {
- ts.gameScene.dump(true)
- } else {
- ts.table.NotifySceneChanged(-1)
- if ts.roomInfo.IsDoublingMode {
- if getCardValue(ts.gameScene.PublicCard) == CardValueJ {
- ts.addDoublingData(Doubling_PublicCard_J)
- ts.sendShowDoublingMsg([]int{Doubling_PublicCard_J})
- }
- }
- }
- }
- func (ts *tablesink) addDoublingData(doubleType int) {
- bFound := false
- valueDouble := []int{}
- if len(ts.roomInfo.ValueDoubling) != VALUE_DOUBLING_LEN {
- valueDouble = append(valueDouble, value_doubling...)
- } else {
- valueDouble = append(valueDouble, ts.roomInfo.ValueDoubling...)
- }
- for i := 0; i < len(ts.gameScene.DoublingDetails); i++ {
- if doubleType == ts.gameScene.DoublingDetails[i].DoublingType {
- ts.gameScene.DoublingDetails[i].DoublingTimes *= valueDouble[doubleType]
- bFound = true
- break
- }
- }
- if !bFound {
- ts.gameScene.DoublingDetails = append(ts.gameScene.DoublingDetails, DoublingData{
- DoublingType: doubleType,
- DoublingTimes: valueDouble[doubleType],
- })
- }
- }
- func (ts *tablesink) sendShowDoublingMsg(doublingTypes []int) {
- var data ShowDoubling
- data.Index = ts.gameScene.Index
- data.Times = 1
- valueDouble := []int{}
- if len(ts.roomInfo.ValueDoubling) != VALUE_DOUBLING_LEN {
- valueDouble = append(valueDouble, value_doubling...)
- } else {
- valueDouble = append(valueDouble, ts.roomInfo.ValueDoubling...)
- }
- for i := 0; i < len(doublingTypes); i++ {
- data.Times *= valueDouble[doublingTypes[i]]
- }
- d, _ := json.Marshal(data)
- ts.table.SendGameData(-1, CMD_SHOWDOUBLING, string(d))
- }
- func (ts *tablesink) recvChatMsg(userIndex int32, data string) {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvChatMsg,user[%d] not exist", userIndex)
- return
- }
- if ts.gameScene.Phase != Phase_Play {
- return
- }
- ts.table.SendGameData(-1, CMD_TABLECHAT, data)
- }
- func (ts *tablesink) recvCancleAutoMsg(userIndex int32, data string) {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvCancleAutoMsg,user[%d] not exist", userIndex)
- return
- }
- chairId := usr.GetUserChairId()
- if chairId == -1 {
- return
- }
- if !ts.gameScene.Players[chairId].AutoOut {
- return
- }
- ts.gameScene.Players[chairId].AutoOut = false
- // 重启倒计时
- if ts.gameScene.WhoseTurn != chairId {
- return
- }
- if ts.gameScene.Phase == Phase_Play {
- ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
- }
- }
- func (ts *tablesink) recvAutoMsg(userIndex int32, data string) {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvAutoMsg,user[%d] not exist", userIndex)
- return
- }
- chairId := usr.GetUserChairId()
- if chairId == -1 {
- return
- }
- ts.gameScene.Players[chairId].AutoOut = true
- // 重启倒计时
- if ts.gameScene.WhoseTurn != chairId {
- return
- }
- if ts.gameScene.Phase == Phase_Play {
- ts.table.SetTimer(TIMER_GAME, SEC_AUTO)
- }
- }
- func (ts *tablesink) recvSyncData(userIndex int32, data string) bool {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvSyncData,user[%d] not exist", userIndex)
- return false
- }
- chairId := usr.GetUserChairId()
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.recvSyncData invalid chair %d", chairId)
- return false
- }
- if !ts.gameScene.Players[chairId].IsValid {
- ts.table.LogWithTableId("tablesink.recvSyncData invalid player [%d]", chairId)
- return false
- }
- if chairId != ts.gameScene.WhoseTurn {
- ts.table.LogWithTableId("tablesink.recvSyncData not WhoseTurn %d != WhoseTurn(%d)", chairId, ts.gameScene.WhoseTurn)
- return false
- }
- if ts.gameScene.Phase != Phase_Correct {
- ts.table.LogWithTableId("tablesink.recvSyncData not CorrectPhase %d", ts.gameScene.Phase)
- return false
- }
- ts.table.SendGameData(-1, CMD_SYNCDATA, data)
- return true
- }
- func (ts *tablesink) recvAction(userIndex int32, data string) bool {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvAction,user[%d] not exist", userIndex)
- return false
- }
- chairId := usr.GetUserChairId()
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.recvAction invalid chair %d", chairId)
- return false
- }
- ts.gameScene.Players[chairId].AutoOut = false
- if !ts.gameScene.Players[chairId].IsValid {
- ts.table.LogWithTableId("tablesink.recvAction invalid player [%d]", chairId)
- return false
- }
- var cmd CmdAction
- e := json.Unmarshal([]byte(data), &cmd)
- if e != nil {
- ts.table.LogWithTableId("tablesink.recvAction Unmarshal failed %s", data)
- return false
- }
- // 重洗阶段不用判断WhoseTurn,只需知道自己是否CanDoReshuffle即可
- if cmd.Action != Action_CorrectionStart {
- if chairId != ts.gameScene.WhoseTurn && ts.gameScene.WhoseTurn != -1 && ts.gameScene.Phase != Phase_Reshuffle {
- ts.table.LogWithTableId("tablesink.recvAction not WhoseTurn %d != WhoseTurn(%d) action[%s] ",
- chairId, ts.gameScene.WhoseTurn, getActionDesc(cmd.Action))
- return false
- }
- }
- ret := false
- errMsg := ""
- switch cmd.Action {
- case Action_Buy:
- ret, errMsg = ts.dealBuy(chairId, cmd.Param)
- case Action_ChooseTrump:
- ret, errMsg = ts.dealChooseTrump(cmd.Param)
- case Action_OutCard:
- ret, errMsg = ts.dealOutCard(cmd.Param, cmd.Projects)
- case Action_CloseOrOpen:
- ret, errMsg = ts.dealCloseOrOpen(cmd.Param)
- case Action_Gawah:
- ret, errMsg = ts.dealGawah()
- case Action_Double:
- ret, errMsg = ts.dealDouble(chairId, cmd.Param)
- case Action_Reshuffle:
- ret, errMsg = ts.dealReshuffle(chairId, cmd.Param)
- case Action_CorrectionStart:
- ret, errMsg = ts.dealCorrectionStart(chairId, cmd.Param)
- case Action_CorrectionFinish:
- ret, errMsg = ts.dealCorrectionFinish(cmd.Param, cmd.CorrectCards)
- case Action_Sawa:
- ret, errMsg = ts.dealSawa()
- }
- if !ret {
- var cmdFailed CmdActionFailed
- cmdFailed.CmdAction = cmd
- cmdFailed.ErrMsg = errMsg
- d, _ := json.Marshal(cmdFailed)
- ts.table.SendGameData(userIndex, CMD_ACTION_FAILED, string(d))
- }
- return ret
- }
- func (ts *tablesink) recvSurrender(userIndex int32, data string) bool {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvSurrender,user[%d] not exist", userIndex)
- return false
- }
- chairId := usr.GetUserChairId()
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.recvSurrender invalid chair %d", chairId)
- return false
- }
- if ts.surrenderInfo.isSurrendering {
- ts.table.LogWithTableId("tablesink.recvSurrender isSurrendering")
- return false
- }
- if ts.gameScene.LeftSurrenderCount <= 0 {
- ts.table.LogWithTableId("tablesink.recvSurrender max operatorCount:%d", ts.gameScene.LeftSurrenderCount)
- return false
- }
- ts.surrenderInfo.isSurrendering = true
- ts.gameScene.LeftSurrenderCount--
- ts.surrenderInfo.WhoseSurrender = chairId
- ts.surrenderInfo.SurrenderResult = Surrender_None
- d := ts.surrenderInfo.getSurrenderInfo()
- ts.table.SendGameData(userIndex, CMD_SURRENDER_RESULT, d)
- friendIndex := ts.table.GetUserByChair(getFriendChair(chairId)).GetUserIndex()
- ts.table.SendGameData(friendIndex, CMD_SURRENDER_RESULT, d)
- // 玩家设置5s倒计时
- if ts.gameScene.Players[getFriendChair(chairId)].isRobot {
- ts.table.SetTimer(TIMER_ROBOT_SURRENDER, 1000+rand.Intn(2000))
- } else {
- ts.table.SetTimer(TIMER_SURRENDER, 5000)
- }
- return true
- }
- func (ts *tablesink) recvSurrenderResult(userIndex int32, data string) bool {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult,user[%d] not exist", userIndex)
- return false
- }
- chairId := usr.GetUserChairId()
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult invalid chair %d", chairId)
- return false
- }
- if !ts.surrenderInfo.isSurrendering {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult not isSurrendering")
- return false
- }
- if getFriendChair(chairId) != ts.surrenderInfo.WhoseSurrender {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult not CorrentChair:%d", chairId)
- return false
- }
- var cmd int
- e := json.Unmarshal([]byte(data), &cmd)
- if e != nil {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult Unmarshal failed %s", data)
- return false
- }
- if cmd != Surrender_Failed && cmd != Surrender_Success {
- ts.table.LogWithTableId("tablesink.recvSurrenderResult cmd ERROR %d", cmd)
- return false
- }
- ts.surrenderInfo.SurrenderResult = cmd
- ts.table.KillTimer(TIMER_SURRENDER)
- d := ts.surrenderInfo.getSurrenderInfo()
- if cmd == Surrender_Success {
- ts.gameScene.Players[ts.surrenderInfo.WhoseSurrender].IsSurrender = true
- ts.table.SendGameData(-1, CMD_SURRENDER_RESULT, d)
- } else {
- ts.surrenderInfo.isSurrendering = false
- friendIndex := ts.table.GetUserByChair(getFriendChair(chairId)).GetUserIndex()
- ts.table.SendGameData(friendIndex, CMD_SURRENDER_RESULT, d)
- }
- return true
- }
- func (ts *tablesink) enterSurrenderEndPhase() {
- // 结算
- winners := []int{}
- surrendChair := ts.surrenderInfo.WhoseSurrender
- winners = append(winners, getNextChair(surrendChair), getPreviousChair(surrendChair))
- totalBet := 0
- if ts.gameScene.Players[winners[0]].bet > 0 {
- totalBet = ts.gameScene.getTotalBet(winners[0])
- }
- // 平分
- endScore := totalBet / len(winners)
- if endScore != 0 {
- for _, v := range winners {
- ts.gameScene.Players[v].EndScore = endScore
- }
- }
- // 写分
- for i := 0; i < CHAIR_COUNT; i++ {
- p := &ts.gameScene.Players[i]
- usr := ts.table.GetUserByChair(i)
- if !p.IsValid || usr == nil {
- continue
- }
- if isSameTeam(i, surrendChair) {
- ts.gameScene.Players[i].TotalScore = 0
- } else {
- ts.gameScene.Players[i].TotalScore = SCORE_TO_WIN
- }
- realWin := p.EndScore - p.bet
- if p.bet == 0 {
- realWin = 0
- }
- tax := 0
- if realWin > 0 {
- tax = realWin * ts.roomInfo.TaxRate / 100
- }
- wScore := p.EndScore - tax
- if p.bet == 0 {
- wScore = 0
- }
- ts.writeScore(p.userID, wScore, tax, 0, scoreType_Surrender, ts.roomInfo.RoomName, p.isRobot)
- if wScore > 0 {
- userservices.DoRecord(p.userID, userservices.Record_MaxWin, wScore)
- }
- if !p.isRobot {
- roomType := waterpool.RoomType_Normal
- if ts.roomInfo.IsDoublingMode {
- roomType = waterpool.RoomType_Doubling
- }
- if ts.roomInfo.RoomType == 3 {
- roomType = waterpool.RoomType_Quick
- }
- if config.Server.IsLadderRoom > 0 {
- roomType = waterpool.RoomType_Ladder
- }
- if p.isControl {
- go waterpool.UpdataUserWaterPool(p.userID, realWin, GAME_NAME, roomType, ts.roomInfo.RoomID)
- } else {
- go waterpool.ReduceInventoryValue(GAMEID, ts.roomInfo.RoomName, realWin-tax, roomType)
- }
- }
- // 写记录
- if ts.table.IsPrivate() {
- } else {
- if p.bet != 0 {
- go ts.table.WriteBetRecordWithSetcount(p.userID, p.bet, wScore, 1.0, "SurrenderGold", "Surrender", ts.roomInfo.RoomName, 1)
- }
- if config.Server.IsLadderRoom > 0 {
- ts.gameScene.Players[i].LastWinCount = ladder.GetUserConsecutiveWinCount(p.userID, GAMEID)
- ts.gameScene.Players[i].LadderChangeValue, _ = ladder.AddUserLadderScore(p.userID, GAMEID, ts.roomInfo.RoomName, wScore-p.bet)
- if ts.gameScene.Players[i].LadderChangeValue > 0 {
- ts.gameScene.Players[i].LastWinCount++
- }
- d := ladder.GetUserLadderInfo(p.userID, GAMEID)
- if d != nil {
- ts.gameScene.Players[i].LadderInfo = *d
- } else {
- ts.table.LogWithTableId("User:%d, LadderInfo is nil", p.userID)
- }
- }
- }
- }
- ts.gameScene.Phase = Phase_End
- ts.table.NotifySceneChanged(-1)
- if ts.table.IsPrivate() {
- winnerUsers := make([]int, len(winners))
- for i := 0; i < len(winners); i++ {
- winnerUsers[i] = ts.gameScene.Players[winners[i]].userID
- }
- ts.table.PrivateRoomSetWinners(winnerUsers)
- ts.writePrivateBetRecords()
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- }
- func (ts *tablesink) dealCloseOrOpen(action int) (bool, string) {
- if ts.gameScene.Phase != Phase_CloseOpen {
- ts.table.LogWithTableId("tablesink.dealCloseOrOpen incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if action != Action_Buy_Open && action != Action_Buy_Close {
- ts.table.LogWithTableId("tablesink.dealCloseOrOpen incorrect action %d", action)
- return false, "Wrong Action"
- }
- if !isValidCard(ts.gameScene.WhoseTurn) {
- ts.table.LogWithTableId("tablesink.dealCloseOrOpen Wrong WhoseTurn:%d", ts.gameScene.WhoseTurn)
- return false, "Wrong ChairId"
- }
- if ts.gameScene.Players[ts.gameScene.WhoseTurn].LastAction == Action_CloseOrOpen {
- ts.table.LogWithTableId("tablesink.dealCloseOrOpen already do CloseOrOpen")
- return false, "Wrong Done Action"
- }
- if action == Action_Buy_Close {
- ts.gameScene.IsClose = true
- ts.logic.setIsFirstOutCardClose(true)
- } else {
- ts.gameScene.IsClose = false
- ts.logic.setIsFirstOutCardClose(false)
- }
- // 记录玩家操作
- ts.gameScene.Players[ts.gameScene.WhoseTurn].LastAction = Action_CloseOrOpen
- ts.gameScene.Players[ts.gameScene.WhoseTurn].LastActionData = action
- ts.gameScene.LastTurn = ts.gameScene.WhoseTurn
- ts.gameScene.addAction(ts.gameScene.WhoseTurn, Action_CloseOrOpen, action)
- ts.gameScene.WhoseTurn = -1
- ts.gameScene.PhaseIndex++
- ts.table.NotifySceneChanged(-1)
- buyAction := Action_Buy_Double + ts.gameScene.BaseTimes - 1
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if isSameTeam(ts.gameScene.LastTurn, i) {
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, buyAction)
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- ts.gameScene.Phase = Phase_Double
- ts.gameScene.PhaseIndex = 0
- ts.table.SetTimer(TIMER_DOUBLE_CHANGE, 600)
- return true, ""
- }
- func (ts *tablesink) dealCorrectionStart(chairId int, mode int) (bool, string) {
- if ts.gameScene.Phase != Phase_Play {
- ts.table.LogWithTableId("tablesink.dealCorrectionStart incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if ts.gameScene.isCorrectEnd {
- return false, "have Corrected"
- }
- if !ts.roomInfo.IsCorrectionMode {
- return false, "not CorrectionMode"
- }
- if isValidChair(ts.gameScene.SawaChair) && chairId == ts.gameScene.SawaChair {
- return false, "SawaChair"
- }
- if !ts.gameScene.CanCorrect {
- return false, "Can Not Operator"
- }
- ts.table.KillAllTimer()
- ts.gameScene.isCorrectEnd = true
- ts.gameScene.CorrectMode = mode
- ts.gameScene.Players[chairId].LastAction = Action_CorrectionStart
- ts.gameScene.LastTurn = chairId
- ts.gameScene.WhoseTurn = chairId
- ts.gameScene.addAction(chairId, Action_CorrectionStart, mode)
- ts.gameScene.PhaseIndex = 0
- ts.gameScene.ShowAllCards = true
- ts.gameScene.Phase = Phase_Correct
- if !ts.simulator.haveWrongAction(ts.gameScene.CorrectMode, ts.gameScene.SawaChair) ||
- (isSameTeam(ts.gameScene.SawaChair, chairId) && ts.gameScene.CorrectMode == Correct_Sawa) {
- ts.gameScene.CorrectResult = 0
- ts.gameScene.PhaseIndex++
- ts.table.NotifySceneChanged(-1)
- ts.table.SetTimer(TIMER_CORRECTFINISH, SEC_CORRECTFINISH)
- return true, ""
- }
- ts.table.NotifySceneChanged(-1)
- ts.DumpScene()
- ts.resetGameTimer()
- return true, ""
- }
- func (ts *tablesink) onTimerCorrectStart() {
- ts.table.KillAllTimer()
- ts.gameScene.CorrectResult = 0
- ts.gameScene.ShowAllCards = true
- ts.gameScene.Index++
- ts.gameScene.PhaseIndex++
- ts.table.NotifySceneChanged(-1)
- ts.table.SetTimer(TIMER_CORRECTFINISH, SEC_CORRECTFINISH)
- }
- func (ts *tablesink) dealCorrectionFinish(correctType int, cards []int) (bool, string) {
- if ts.gameScene.Phase != Phase_Correct {
- ts.table.LogWithTableId("tablesink.dealReshuffle incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if !ts.roomInfo.IsCorrectionMode {
- return false, "not CorrectionMode"
- }
- if ts.gameScene.CorrectMode == Correct_Invaild {
- return false, "Invaild CorrectMode"
- }
- if len(cards) != 2 {
- return false, "Wrong Cards"
- }
- if ts.gameScene.PhaseIndex != 0 {
- return false, "Wrong Phase Index"
- }
- ts.table.KillAllTimer()
- ts.gameScene.Players[ts.gameScene.WhoseTurn].LastAction = Action_CorrectionFinish
- ts.gameScene.LastTurn = ts.gameScene.WhoseTurn
- ts.gameScene.addCorrectAction(ts.gameScene.WhoseTurn, Action_CorrectionFinish, correctType, cards)
- ts.gameScene.PhaseIndex++
- ts.gameScene.CorrectCards = append(ts.gameScene.CorrectCards, cards...)
- if ts.gameScene.CorrectMode == Correct_Sawa {
- ts.gameScene.CorrectResult = ts.simulator.checkWrongActionInSawa(ts.gameScene.SawaChair, cards)
- } else {
- ts.gameScene.CorrectResult = ts.simulator.checkWrongActionInNormal(ts.gameScene.WhoseTurn, correctType, cards)
- }
- ts.gameScene.ShowAllCards = true
- ts.gameScene.CorrectType = correctType
- ts.table.NotifySceneChanged(-1)
- ts.table.SetTimer(TIMER_CORRECTFINISH, SEC_CORRECTFINISH)
- return true, ""
- }
- func (ts *tablesink) onTimerCorrectFinish() {
- winChair := ts.gameScene.WhoseTurn
- if ts.gameScene.CorrectResult == 0 {
- winChair = getNextChair(winChair)
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if ts.gameScene.Players[i].HaveBaloot && !ts.gameScene.Players[i].isIncludeBaloot() &&
- ts.gameScene.CorrectMode == Correct_Normal {
- ts.gameScene.Players[i].Projects = append(ts.gameScene.Players[i].Projects, SingleProject{
- Type: PROJECT_BALOOT,
- Score: value_project[PROJECT_BALOOT],
- Cards: []int{genACard(ts.gameScene.TrumpType, CardValueQ), genACard(ts.gameScene.TrumpType, CardValueK)},
- })
- if ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(Doubling_Project_Baloot)
- }
- }
- if isSameTeam(i, winChair) {
- if ts.gameScene.FinalClub == Suit_Hokum {
- ts.gameScene.Players[i].WinCardScore = HOKUM_TOTAL_SCORE
- } else {
- ts.gameScene.Players[i].WinCardScore = SUN_TOTAL_SCORE
- }
- } else {
- ts.gameScene.Players[i].WinCardScore = 0
- }
- }
- ts.gameScene.Players[winChair].WinCardNumber += ts.gameScene.getLeftCardNumber()
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].clearHandCard()
- }
- ts.gameScene.RoundWinner = winChair
- ts.onTimerNewRound()
- }
- func (ts *tablesink) dealReshuffle(chairId int, action int) (bool, string) {
- if ts.gameScene.Phase != Phase_Reshuffle {
- ts.table.LogWithTableId("tablesink.dealReshuffle incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- p := &ts.gameScene.Players[chairId]
- if !p.CanDoReshuffle || p.ReshuffleAction != Reshuffle_None {
- ts.table.LogWithTableId("tablesink.dealReshuffle Can not do the action %d", action)
- return false, "Wrong Action"
- }
- if ts.gameScene.havePlayerConfirmReshuffle(chairId) {
- ts.table.LogWithTableId("tablesink.dealReshuffle Can not do the action %d", action)
- return false, "Wrong Action"
- }
- // 记录玩家操作
- ts.gameScene.Players[chairId].LastAction = Action_Reshuffle
- ts.gameScene.Players[chairId].LastActionData = action
- ts.gameScene.Players[chairId].ReshuffleAction = action
- ts.gameScene.LastTurn = chairId
- ts.gameScene.addAction(chairId, Action_Reshuffle, action)
- ts.gameScene.PhaseIndex++
- if action == Reshuffle_Confirm {
- ts.gameScene.WhoseTurn = -1
- ts.gameScene.reshuffleResult = -1
- ts.table.NotifySceneChanged(-1)
- ts.table.SetTimer(TIMER_ALL_PASS, SEC_ALL_PASS*30)
- return true, ""
- }
- if ts.gameScene.isAllCanDoReshufflePlayerPass() {
- ts.gameScene.Phase = ts.gameScene.reshufflePhase
- ts.gameScene.PhaseIndex = 0
- ts.gameScene.LastTurn = ts.gameScene.BuyChair
- if ts.gameScene.reshuffleResult == 0 {
- ts.resetGameTimer()
- } else {
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- }
- }
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- func (ts *tablesink) dealDouble(chairId int, buyAction int) (bool, string) {
- if ts.gameScene.Phase != Phase_Double {
- ts.table.LogWithTableId("tablesink.dealDouble incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- p := &ts.gameScene.Players[chairId]
- if !p.canDoBuyAction(buyAction) {
- ts.table.LogWithTableId("tablesink.dealDouble Can not do the buy action %d", buyAction)
- return false, "Wrong Action"
- }
- // 记录玩家操作
- ts.gameScene.Players[chairId].LastAction = Action_Double
- ts.gameScene.Players[chairId].LastActionData = buyAction
- ts.gameScene.LastTurn = chairId
- ts.gameScene.PhaseIndex++
- ts.gameScene.addAction(chairId, Action_Double, buyAction)
- ts.gameScene.initAllPlayerTime()
- if buyAction != Action_Buy_Pass && ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(buyAction)
- ts.sendShowDoublingMsg([]int{buyAction})
- }
- if buyAction == Action_Buy_Double && ts.gameScene.FinalClub != Suit_Hokum {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].setPlayerOperators([]int{})
- }
- ts.gameScene.setBaseTimes(buyAction)
- ts.gameScene.BuyChair = chairId
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- if ts.gameScene.isAllPlayerPass() {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].setPlayerOperators([]int{})
- }
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- ts.gameScene.Players[chairId].setPlayerOperators([]int{})
- if buyAction == Action_Buy_Coffee {
- ts.gameScene.IsClose = false
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].setPlayerOperators([]int{})
- }
- ts.gameScene.BaseTimes = 1
- ts.gameScene.BuyChair = chairId
- ts.gameScene.IsBO1 = true
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- if buyAction != Action_Buy_Pass {
- ts.gameScene.setBaseTimes(buyAction)
- ts.gameScene.BuyChair = chairId
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- ts.table.NotifySceneChanged(-1)
- if ts.gameScene.BaseTimes%2 != 0 {
- ts.gameScene.WhoseTurn = -1
- ts.gameScene.IsClose = false
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if isSameTeam(chairId, i) {
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, buyAction+1)
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- } else {
- ts.gameScene.WhoseTurn = ts.gameScene.BuyChair
- ts.gameScene.Phase = Phase_CloseOpen
- ts.gameScene.PhaseIndex = 0
- }
- ts.table.SetTimer(TIMER_DOUBLE_CHANGE, 100)
- return true, ""
- }
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- func (ts *tablesink) isFirstBuyEnterSecondBuy(chairId, buyAction int) bool {
- return (chairId == ts.gameScene.Banker && ts.gameScene.Phase == Phase_FirstBuy &&
- buyAction == Action_Buy_Pass && ts.gameScene.BuyAction <= Action_Buy_Pass)
- }
- func (ts *tablesink) dealBuy(chairId int, buyAction int) (bool, string) {
- if ts.gameScene.Phase != Phase_FirstBuy && ts.gameScene.Phase != Phase_SecondBuy {
- ts.table.LogWithTableId("tablesink.dealBuy incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- p := &ts.gameScene.Players[chairId]
- if !p.canDoBuyAction(buyAction) {
- ts.table.LogWithTableId("tablesink.dealBuy Chair:%d Can not do the buy action %d", chairId, buyAction)
- return false, "Wrong Action"
- }
- if ts.gameScene.WhoseTurn != -1 {
- if chairId != ts.gameScene.WhoseTurn {
- ts.table.LogWithTableId("tablesink.dealBuy not the chairId %d", chairId)
- return false, "Wrong chairId"
- }
- }
- // 记录玩家操作
- ts.gameScene.Players[chairId].LastAction = Action_Buy
- ts.gameScene.Players[chairId].LastActionData = buyAction
- ts.gameScene.LastTurn = chairId
- ts.gameScene.initAllPlayerTime()
- ts.gameScene.Players[chairId].setPlayerOperators([]int{})
- ts.gameScene.addAction(chairId, Action_Buy, buyAction)
- ts.gameScene.buyPhase = ts.gameScene.Phase
- // 查看是否触发加倍
- if ts.roomInfo.IsDoublingMode && !isSameTeam(ts.gameScene.BuyChair, chairId) {
- if ts.gameScene.BuyAction == Action_Buy_Hokum && buyAction == Action_Buy_Ashkal {
- ts.addDoublingData(Doubling_Hokum_to_Ashkal)
- ts.sendShowDoublingMsg([]int{Doubling_Hokum_to_Ashkal})
- }
- if ts.gameScene.BuyAction == Action_Buy_Hokum && buyAction == Action_Buy_Sun {
- ts.addDoublingData(Doubling_Hokum_to_Sun)
- ts.sendShowDoublingMsg([]int{Doubling_Hokum_to_Sun})
- }
- if ts.gameScene.BuyAction == Action_Buy_Ashkal && buyAction == Action_Buy_Sun {
- ts.addDoublingData(Doubling_Ashkal_to_Sun)
- ts.sendShowDoublingMsg([]int{Doubling_Ashkal_to_Sun})
- }
- if ts.gameScene.BuyAction == Action_Buy_Sun && buyAction == Action_Buy_Sun {
- ts.addDoublingData(Doubling_Sun_to_Sun)
- ts.sendShowDoublingMsg([]int{Doubling_Sun_to_Sun})
- }
- }
- if buyAction == Action_Buy_ConfirmHokum || buyAction == Action_Buy_SwitchSun ||
- ts.gameScene.isBuySunEnterDouble(buyAction, chairId) ||
- ts.gameScene.canReshuffle(buyAction, chairId) || ts.isFirstBuyEnterSecondBuy(chairId, buyAction) {
- ts.gameScene.PhaseIndex++
- ts.table.NotifySceneChanged(-1)
- }
- // 判断买牌玩家是否有变化
- buyChairIsChange := false
- if (buyAction > Action_Buy_Pass && buyAction <= Action_Buy_Ashkal) || ts.gameScene.BuyAction <= Action_Buy_Pass {
- buyChairIsChange = true
- }
- // 两轮都不买重洗
- if ts.gameScene.WhoseTurn == ts.gameScene.Banker &&
- ts.gameScene.BuyAction <= Action_Buy_Pass &&
- ts.gameScene.Phase == Phase_SecondBuy && buyAction == Action_Buy_Pass {
- ts.gameScene.WhoseTurn = -1
- ts.gameScene.PhaseIndex++
- ts.table.NotifySceneChanged(-1)
- ts.allPassCount++
- ts.table.SetTimer(TIMER_ALL_PASS, SEC_ALL_PASS*5)
- return true, ""
- }
- result := 0
- prePhase := ts.gameScene.Phase
- if buyChairIsChange {
- result = ts.gameScene.resetBuyActionOfChangeBuyChair(buyAction, chairId)
- if ts.gameScene.isEnterReshuffle(buyAction) {
- ts.gameScene.reshuffleResult = result
- ts.resetGameTimer()
- } else {
- if result == 0 {
- ts.resetGameTimer()
- } else {
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- }
- }
- if prePhase != ts.gameScene.Phase {
- ts.gameScene.initAllPlayerLastAction()
- } else {
- ts.gameScene.PhaseIndex++
- }
- // 特殊要求First_Buy切换到Second_Buy阶段,做延迟处理
- if prePhase == Phase_FirstBuy && ts.gameScene.Phase == Phase_SecondBuy {
- ts.table.SetTimer(TIMER_BUY_CHANGE, 100)
- return true, ""
- }
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- result = ts.gameScene.resetBuyActionOfNotChangeBuyChair(chairId, buyAction)
- isConfirmHokum := false
- if buyAction == Action_Buy_ConfirmHokum && prePhase == Phase_FirstBuy {
- isConfirmHokum = true
- data := ShowCardType{Type: ts.gameScene.TrumpType, Chair: chairId}
- d, _ := json.Marshal(data)
- ts.table.SendGameData(-1, CMD_SHOW_CARDTYPE, string(d))
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- }
- ts.gameScene.Index++
- ts.table.NotifySceneChanged(-1)
- if result == 1 {
- if !isConfirmHokum {
- ts.resetGameTimer()
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if isSameTeam(i, ts.gameScene.BuyChair) {
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Double)
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- ts.table.SetTimer(TIMER_DOUBLE_CHANGE, 2200)
- }
- } else if result == 2 {
- ts.table.SetTimer(TIMER_SEND_LEFT_CARD, SEC_SEND_LEFT_CARD)
- }
- if prePhase != ts.gameScene.Phase {
- ts.gameScene.initAllPlayerLastAction()
- }
- return true, ""
- }
- func (ts *tablesink) killAutoTimer() {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.table.KillTimer(TIMER_AUTO_ACTION_0 + i)
- }
- }
- func (ts *tablesink) resetGameTimer() {
- ts.LastOpraTime = time.Now()
- ts.killAutoTimer()
- switch ts.gameScene.Phase {
- case Phase_Start:
- ts.table.SetTimer(TIMER_GAME, SEC_START)
- case Phase_GameEnd:
- if ts.gameScene.ScoreToWin == -1 && !ts.table.IsPrivate() {
- ts.table.SetTimer(TIMER_GAME, 500)
- } else {
- if config.Server.IsLadderRoom == 1 && (ts.gameScene.ScoreToWin+ts.gameScene.GameIndex) < -1 {
- ts.table.SetTimer(TIMER_GAME, 6000)
- } else {
- if config.Server.IsLadderRoom == 1 && (ts.gameScene.ScoreToWin+ts.gameScene.GameIndex) == -1 {
- ts.table.SetTimer(TIMER_GAME, 500)
- } else {
- ts.table.SetTimer(TIMER_GAME, 500)
- }
- }
- }
- case Phase_Correct:
- ts.table.SetTimer(TIMER_GAME, 60000)
- case Phase_Reshuffle:
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil || usr.IsRobot() {
- continue
- }
- if !ts.gameScene.Players[i].AutoOut {
- continue
- }
- if !ts.gameScene.Players[i].canReshuffle() {
- continue
- }
- ts.table.SetTimer(TIMER_AUTO_ACTION_0+i, SEC_AUTO)
- }
- ts.table.SetTimer(TIMER_GAME, SEC_RESHUFFLE)
- default:
- if ts.gameScene.WhoseTurn == -1 {
- ts.checkAutoPlayerAction()
- ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
- } else {
- if !isValidChair(ts.gameScene.WhoseTurn) {
- return
- }
- chairId := ts.gameScene.WhoseTurn
- usr := ts.table.GetUserByChair(chairId)
- if usr == nil {
- ts.table.LogWithTableId("resetGameTimer Phase:%d ChairId:%d nnot exist", ts.gameScene.Phase, chairId)
- ts.gameScene.Phase = Phase_End
- ts.gameScene.PhaseIndex = 0
- // 分数还原
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- if ts.gameScene.Players[i].bet > 0 {
- ts.writeScore(ts.gameScene.Players[i].userID, ts.gameScene.Players[i].bet, 0, 0,
- ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
- }
- }
- if ts.table.IsPrivate() {
- ts.table.PrivateRoomSetWinners([]int{})
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- return
- }
- if isValidChair(chairId) {
- if (ts.gameScene.Players[chairId].AutoOut || usr.GetUserStatus() == user.UserStatus_Offline) &&
- !usr.IsRobot() {
- ts.table.SetTimer(TIMER_GAME, SEC_AUTO)
- } else {
- ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
- }
- } else {
- ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
- }
- }
- }
- if ts.gameScene.Phase == Phase_Play {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.table.KillTimer(TIMER_ROBOT_SEND_CHAT_0 + i)
- }
- ts.table.SetTimer(TIMER_ROBOT_SEND_CHAT_0+ts.gameScene.WhoseTurn, 5000)
- }
- ts.checkRobotAction()
- }
- func (ts *tablesink) getSecond(phase int) int {
- ret := 0
- switch phase {
- case Phase_FirstBuy:
- fallthrough
- case Phase_SecondBuy:
- ret = ts.roomInfo.SecBuy
- case Phase_ChooseTrump:
- ret = ts.roomInfo.SecChooseTrump
- case Phase_Double:
- ret = ts.roomInfo.SecDouble
- case Phase_CloseOpen:
- ret = ts.roomInfo.SecCloseOpen
- case Phase_Reshuffle:
- ret = SEC_RESHUFFLE
- case Phase_Play:
- if isValidChair(ts.gameScene.WhoseTurn) && len(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards) == 1 {
- ret = 700
- } else {
- ret = ts.roomInfo.SecPlay
- }
- }
- if ret < 100 {
- ret *= 1000
- }
- if ret == 0 {
- ret = 20000
- }
- return ret
- }
- func (ts *tablesink) checkAutoPlayerAction() {
- if ts.gameScene.WhoseTurn != -1 {
- return
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil || usr.IsRobot() || !ts.gameScene.Players[i].canAction() {
- continue
- }
- if !ts.gameScene.Players[i].AutoOut {
- continue
- }
- ts.table.SetTimer(TIMER_AUTO_ACTION_0+i, SEC_AUTO)
- }
- }
- func (ts *tablesink) onTimerBuyFailed() {
- if ts.gameScene.Phase == Phase_End {
- return
- }
- if ts.surrenderInfo.isSurrenderEnd() {
- ts.gameScene.BuyChair = getNextChair(ts.surrenderInfo.WhoseSurrender)
- ts.gameScene.FinalClub = Suit_Sun
- ts.gameScene.LastWinChair = ts.gameScene.BuyChair
- ts.gameScene.Players[ts.gameScene.BuyChair].FinalCalcScore = 26
- ts.gameScene.Players[ts.gameScene.BuyChair].TotalScore += 26
- ts.gameScene.Players[getFriendChair(ts.gameScene.BuyChair)].FinalCalcScore = 26
- ts.gameScene.Players[getFriendChair(ts.gameScene.BuyChair)].TotalScore += 26
- ts.enterGameEndPhase(false)
- return
- }
- ts.gameScene.setNextBanker()
- ts.gameScene.gameInit(getPreviousChair(ts.gameScene.Banker))
- ts.gameStart()
- if ts.gameScene.GameIndex == 0 {
- ts.table.NotifySceneChanged(-1)
- if ts.roomInfo.IsDoublingMode {
- if getCardValue(ts.gameScene.PublicCard) == CardValueJ {
- ts.addDoublingData(Doubling_PublicCard_J)
- ts.sendShowDoublingMsg([]int{Doubling_PublicCard_J})
- }
- }
- }
- }
- func (ts *tablesink) sendLeftCard() {
- ts.logic.setTrumpAndSuit(ts.gameScene.TrumpType, ts.gameScene.FinalClub)
- getPublicChairId := ts.gameScene.BuyChair
- ts.gameScene.Phase = Phase_SendLeftCard
- ts.gameScene.PhaseIndex = 0
- if ts.gameScene.FinalClub == Suit_Ashkal {
- getPublicChairId = (getPublicChairId + 2) % CHAIR_COUNT
- }
- count := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- if userStatus <= user.UserStatus_Free ||
- userStatus == user.UserStatus_Watch {
- continue
- }
- count++
- leftCards := ts.logic.getLeftCards(getPublicChairId == i)
- ts.gameScene.Players[i].HandCards = append(ts.gameScene.Players[i].HandCards, leftCards...)
- ts.gameScene.Players[i].LeftSendCards = append(ts.gameScene.Players[i].LeftSendCards, leftCards...)
- if getPublicChairId == i {
- ts.gameScene.Players[i].HandCards = append(ts.gameScene.Players[i].HandCards, ts.gameScene.PublicCard)
- ts.gameScene.Players[i].LeftSendCards = append(ts.gameScene.Players[i].LeftSendCards, ts.gameScene.PublicCard)
- }
- if ts.gameScene.FinalClub == Suit_Hokum {
- ts.gameScene.Players[i].checkBaloot(ts.gameScene.TrumpType)
- }
- p := &ts.gameScene.Players[i]
- sort.Slice(p.HandCards, func(m, n int) bool {
- return getCardSortValue(p.HandCards[m], ts.gameScene.TrumpType) <
- getCardSortValue(p.HandCards[n], ts.gameScene.TrumpType)
- })
- }
- if count < CHAIR_COUNT {
- ts.table.LogWithTableId("sendLeftCard 用户不足")
- ts.gameScene.Phase = Phase_End
- ts.gameScene.PhaseIndex = 0
- // 分数还原
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- if ts.gameScene.Players[i].bet > 0 {
- ts.writeScore(ts.gameScene.Players[i].userID, ts.gameScene.Players[i].bet, 0, 0,
- ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
- }
- }
- if ts.table.IsPrivate() {
- ts.table.PrivateRoomSetWinners([]int{})
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- return
- }
- ts.gameScene.onAllCardsSent()
- ts.table.SetTimer(TIMER_START_OUT_CARD, SEC_START_OUT_CARD)
- ts.table.NotifySceneChanged(-1)
- }
- func (ts *tablesink) dealChooseTrump(t int) (bool, string) {
- if ts.gameScene.Phase != Phase_ChooseTrump {
- ts.table.LogWithTableId("tablesink.dealChooseTrump incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if t == getCardType(ts.gameScene.PublicCard) || t >= CardType_Invalid {
- ts.table.LogWithTableId("tablesink.dealChooseTrump incorrect Type %d", t)
- return false, "Wrong Type"
- }
- ts.gameScene.FinalClub = Suit_Hokum
- ts.gameScene.TrumpType = t
- data := ShowCardType{Type: t, Chair: ts.gameScene.WhoseTurn}
- d, _ := json.Marshal(data)
- ts.table.SendGameData(-1, CMD_SHOW_CARDTYPE, string(d))
- chair := ts.gameScene.WhoseTurn
- ts.gameScene.LastTurn = chair
- ts.gameScene.Players[chair].LastAction = Action_ChooseTrump
- ts.gameScene.Players[chair].LastActionData = t
- ts.gameScene.addAction(chair, Action_ChooseTrump, t)
- ts.gameScene.PhaseIndex++
- ts.gameScene.WhoseTurn = -1
- ts.table.NotifySceneChanged(-1)
- for i := 0; i < CHAIR_COUNT; i++ {
- p := &ts.gameScene.Players[i]
- sort.Slice(p.HandCards, func(m, n int) bool {
- return getCardSortValue(p.HandCards[m], ts.gameScene.TrumpType) <
- getCardSortValue(p.HandCards[n], ts.gameScene.TrumpType)
- })
- buyList := []int{}
- if isSameTeam(i, ts.gameScene.BuyChair) {
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Double)
- ts.gameScene.Players[i].setPlayerOperators(buyList)
- }
- ts.gameScene.Phase = Phase_Double
- ts.gameScene.PhaseIndex = 0
- ts.table.SetTimer(TIMER_DOUBLE_CHANGE, 2200)
- return true, ""
- }
- func (ts *tablesink) dealSawa() (bool, string) {
- if ts.gameScene.Phase != Phase_Play {
- ts.table.LogWithTableId("tablesink.dealSawa incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if ts.gameScene.WhoseTurn == -1 {
- ts.table.LogWithTableId("tablesink.dealSawa not correct WhoseTurn %d", ts.gameScene.WhoseTurn)
- return false, "Wrong WhoseTurn"
- }
- if ts.gameScene.RoundType != CardType_Invalid {
- ts.table.LogWithTableId("tablesink.dealSawa Not First OutCard")
- return false, "Not First OutCard"
- }
- if isValidChair(ts.gameScene.SawaChair) {
- ts.table.LogWithTableId("tablesink.dealSawa Already Sawa")
- return false, "Already Sawa"
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if ts.gameScene.Players[i].HaveBaloot && !ts.gameScene.Players[i].isIncludeBaloot() {
- ts.gameScene.Players[i].Projects = append(ts.gameScene.Players[i].Projects, SingleProject{
- Type: PROJECT_BALOOT,
- Score: value_project[PROJECT_BALOOT],
- Cards: []int{genACard(ts.gameScene.TrumpType, CardValueQ), genACard(ts.gameScene.TrumpType, CardValueK)},
- })
- d, _ := json.Marshal(i)
- ts.table.SendGameData(-1, CMD_CALL_BALOOT, string(d))
- if ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(Doubling_Project_Baloot)
- ts.sendShowDoublingMsg([]int{Doubling_Project_Baloot})
- }
- }
- }
- if ts.roomInfo.IsCorrectionMode {
- ts.gameScene.CanCorrect = true
- }
- ts.table.KillAllTimer()
- p := &ts.gameScene.Players[ts.gameScene.WhoseTurn]
- ts.gameScene.LastTurn = ts.gameScene.WhoseTurn
- p.LastAction = Action_Sawa
- ts.gameScene.addAction(ts.gameScene.WhoseTurn, Action_Sawa, ts.gameScene.WhoseTurn)
- ts.gameScene.PhaseIndex++
- ts.gameScene.ShowAllCards = true
- ts.gameScene.SawaChair = ts.gameScene.WhoseTurn
- ts.table.NotifySceneChanged(-1)
- if ts.roomInfo.IsCorrectionMode {
- ts.table.SetTimer(TIMER_SAWA, SEC_SAWA)
- } else {
- ts.table.SetTimer(TIMER_SAWA, 2200)
- }
- return true, ""
- }
- func (ts *tablesink) onTimerSawa() {
- if ts.gameScene.Phase != Phase_Play {
- ts.table.LogWithTableId("tablesink.dealSawa incorrect phase %d", ts.gameScene.Phase)
- return
- }
- chair := ts.gameScene.WhoseTurn
- winChair := chair
- if !ts.roomInfo.IsCorrectionMode {
- for n := 0; n < CHAIR_COUNT; n++ {
- for i := 0; i <= len(ts.gameScene.Players[chair].HandCards); i++ {
- card := ts.gameScene.Players[chair].HandCards[i]
- if !ts.simulator.isBiggerThanAll(card, getCardType(card), ts.gameScene.Players[n].HandCards) {
- winChair = n
- break
- }
- }
- if winChair != chair {
- if isSameTeam(winChair, chair) {
- winChair = getNextChair(chair)
- }
- break
- }
- }
- }
- leftScore := 0
- getScore := ts.gameScene.Players[winChair].WinCardScore + ts.gameScene.Players[getNextChair(winChair)].WinCardScore
- if ts.gameScene.FinalClub == Suit_Hokum {
- leftScore = HOKUM_TOTAL_SCORE - getScore
- } else {
- leftScore = SUN_TOTAL_SCORE - getScore
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, winChair) {
- ts.gameScene.Players[i].WinCardScore += leftScore
- }
- }
- ts.gameScene.ShowAllCards = true
- ts.gameScene.CanCorrect = false
- ts.gameScene.Players[winChair].WinCardNumber += ts.gameScene.getLeftCardNumber()
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].clearHandCard()
- }
- ts.gameScene.RoundWinner = winChair
- ts.onTimerNewRound()
- }
- func (ts *tablesink) dealGawah() (bool, string) {
- if ts.gameScene.Phase != Phase_Play {
- ts.table.LogWithTableId("tablesink.dealGawah incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if ts.gameScene.WhoseTurn == -1 {
- ts.table.LogWithTableId("tablesink.dealGawah not correct WhoseTurn %d", ts.gameScene.WhoseTurn)
- return false, "Wrong WhoseTurn"
- }
- chair := ts.gameScene.WhoseTurn
- p := &ts.gameScene.Players[chair]
- if !p.CanGawah {
- ts.table.LogWithTableId("tablesink.dealGawah can not Gawah")
- return false, "Wrong Action"
- }
- ts.gameScene.LastTurn = chair
- p.LastAction = Action_Gawah
- p.CanGawah = false
- ts.gameScene.addAction(chair, Action_Gawah, chair)
- ts.gameScene.PhaseIndex++
- ts.table.KillTimer(TIMER_GAME)
- leftScore := ts.gameScene.getLeftScore()
- ts.gameScene.Players[chair].winCardScore += leftScore
- doublingData := []int{}
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, chair) {
- ts.gameScene.Players[i].addScore(leftScore)
- } else {
- ts.gameScene.Players[i].addScore(0)
- }
- if ts.gameScene.Players[i].HaveBaloot && !ts.gameScene.Players[i].isIncludeBaloot() {
- ts.gameScene.Players[i].Projects = append(ts.gameScene.Players[i].Projects, SingleProject{
- Type: PROJECT_BALOOT,
- Score: value_project[PROJECT_BALOOT],
- Cards: []int{genACard(ts.gameScene.TrumpType, CardValueQ), genACard(ts.gameScene.TrumpType, CardValueK)},
- })
- d, _ := json.Marshal(i)
- ts.table.SendGameData(-1, CMD_CALL_BALOOT, string(d))
- if ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(Doubling_Project_Baloot)
- doublingData = append(doublingData, Doubling_Project_Baloot)
- }
- }
- }
- ts.gameScene.ShowAllCards = true
- winCardNum := ts.gameScene.getLeftCardNumber()
- preWinCount := ts.gameScene.Players[chair].consecutiveWinCardCount
- ts.gameScene.Players[chair].consecutiveWinCardCount += winCardNum / CHAIR_COUNT
- ts.gameScene.Players[getFriendChair(chair)].consecutiveWinCardCount += winCardNum / CHAIR_COUNT
- ts.gameScene.Players[chair].WinCardNumber += winCardNum
- if ts.gameScene.Players[chair].consecutiveWinCardCount >= 5 && ts.roomInfo.IsDoublingMode {
- leftCount := 0
- if preWinCount >= 5 {
- leftCount = ts.gameScene.Players[chair].consecutiveWinCardCount - preWinCount
- } else {
- leftCount = ts.gameScene.Players[chair].consecutiveWinCardCount - 4
- }
- winData := []int{}
- for i := 0; i < leftCount; i++ {
- ts.addDoublingData(Doubling_ConsecutiveWinOverFour)
- winData = append(winData, Doubling_ConsecutiveWinOverFour)
- }
- doublingData = append(doublingData, winData...)
- }
- if len(doublingData) > 0 {
- ts.sendShowDoublingMsg(doublingData)
- }
- ts.table.NotifySceneChanged(-1)
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].clearHandCard()
- }
- ts.gameScene.RoundWinner = chair
- ts.table.SetTimer(TIMER_NEWROUND, 2200)
- return true, ""
- }
- func (ts *tablesink) dealOutCard(card int, projects []int) (bool, string) {
- if ts.gameScene.Phase != Phase_Play {
- ts.table.LogWithTableId("tablesink.dealOutCard incorrect phase %d", ts.gameScene.Phase)
- return false, "Wrong Phase"
- }
- if ts.gameScene.WhoseTurn == -1 {
- ts.table.LogWithTableId("tablesink.dealOutCard incorrect WhoseTurn %d", ts.gameScene.WhoseTurn)
- return false, "Wrong WhoseTurn"
- }
- chair := ts.gameScene.WhoseTurn
- p := &ts.gameScene.Players[chair]
- if ts.gameScene.isFirstOutCardInCloseMode() && !ts.roomInfo.IsCorrectionMode {
- if getCardType(card) == ts.gameScene.TrumpType && !p.IsAllTrumpCard(ts.gameScene.TrumpType) {
- ts.table.LogWithTableId("tablesink.dealOutCard OutCard Fail")
- return false, "Wrong Card"
- }
- }
- if isValidChair(ts.gameScene.SawaChair) {
- return false, "is In Sawa"
- }
- // 检查牌是否能出
- if !ts.simulator.fakers[chair].isOutBigCards(card) && !ts.roomInfo.IsCorrectionMode {
- ts.table.LogWithTableId("tablesink.dealOutCard not Out BigCard %d, BigCard%s", card, getCardsHex(p.BigCards))
- return false, "Wrong BigCard"
- }
- // 检查牌是否能出
- if !ts.logic.canOut(card, ts.gameScene.RoundType, p.HandCards) && !ts.roomInfo.IsCorrectionMode {
- ts.table.LogWithTableId("tablesink.dealOutCard removeCard failed %d", card)
- return false, "Wrong Card Type"
- }
- handCards := make([]int, len(p.HandCards))
- copy(handCards, p.HandCards)
- // 牌在不在?
- if !p.removeCard(card) {
- ts.table.LogWithTableId("tablesink.dealOutCard removeCard failed %d", card)
- return false, "Card Not Exist"
- }
- // 纠错模式,记录玩家出牌是否正确
- if ts.roomInfo.IsCorrectionMode {
- flag := -1
- correctType := CorrectType_Invaild
- shouldOutCards := []int{}
- if ts.gameScene.isFirstOutCardInCloseMode() {
- if getCardType(card) == ts.gameScene.TrumpType && !p.IsAllTrumpCard(ts.gameScene.TrumpType) {
- flag = card
- correctType = CorrectType_Close
- for n := 0; n < len(handCards); n++ {
- if getCardType(handCards[n]) != ts.gameScene.TrumpType {
- shouldOutCards = append(shouldOutCards, handCards[n])
- }
- }
- }
- }
- if !ts.simulator.fakers[chair].isOutBigCards(card) {
- flag = card
- for n := 0; n < len(handCards); n++ {
- if ts.simulator.fakers[chair].isOutBigCards(handCards[n]) {
- shouldOutCards = append(shouldOutCards, handCards[n])
- }
- }
- if ts.gameScene.RoundType == ts.gameScene.TrumpType {
- correctType = CorrectType_BigCardInHokum
- } else {
- correctType = CorrectType_TrumpCard
- }
- }
- if !ts.logic.canOut(card, ts.gameScene.RoundType, handCards) {
- flag = card
- correctType = CorrectType_SameType
- for n := 0; n < len(handCards); n++ {
- if ts.logic.canOut(handCards[n], ts.gameScene.RoundType, handCards) {
- shouldOutCards = append(shouldOutCards, handCards[n])
- }
- }
- }
- ts.simulator.fakers[chair].correctionList = append(ts.simulator.fakers[chair].correctionList, correction{
- correctCard: flag,
- correctType: correctType,
- suggestCards: shouldOutCards,
- })
- }
- ts.simulator.fakers[chair].removeCard(card)
- if ts.gameScene.RoundType != CardType_Invalid && getCardType(card) != ts.gameScene.RoundType {
- ts.simulator.fakers[chair].updataACardTypeToNotExist(ts.gameScene.RoundType)
- }
- if p.CanGawah {
- p.CanGawah = false
- }
- ts.gameScene.LastTurn = chair
- p.LastAction = Action_OutCard
- p.LastActionData = card
- p.IsCallBiggest = false
- ts.gameScene.addOutCardAction(chair, Action_OutCard, card, projects)
- doublingData := []int{}
- if getCardType(card) == ts.gameScene.TrumpType &&
- (getCardValue(card) == CardValueQ || getCardValue(card) == CardValueK) &&
- p.outAllBalootCard(ts.gameScene.TrumpType) {
- p.Projects = append(p.Projects, SingleProject{
- Type: PROJECT_BALOOT,
- Score: value_project[PROJECT_BALOOT],
- Cards: []int{genACard(ts.gameScene.TrumpType, CardValueQ), genACard(ts.gameScene.TrumpType, CardValueK)},
- })
- d, _ := json.Marshal(ts.gameScene.WhoseTurn)
- ts.table.SendGameData(-1, CMD_CALL_BALOOT, string(d))
- if ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(Doubling_Project_Baloot)
- doublingData = append(doublingData, Doubling_Project_Baloot)
- }
- }
- if ts.gameScene.RoundIndex == 1 && len(projects) == 4 {
- ts.gameScene.checkProject(chair, projects)
- for n := 0; n < len(ts.gameScene.Players[chair].Projects); n++ {
- //if ts.gameScene.Players[chair].CallProject == PROJECT_FOURHUNDRED {
- var param badge.Scope
- param.GameName = GAME_NAME
- param.RankInfo.Score = ts.gameScene.Players[chair].Projects[n].taskScore
- userId := ts.gameScene.Players[chair].userID
- badge.DoAction(userId, badge.Action_Game_CallPoints, 1, param)
- }
- }
- // 加倍模式项目加倍
- if ts.roomInfo.IsDoublingMode && ts.gameScene.RoundIndex == 1 && len(p.Projects) > 0 {
- projectData := []int{}
- for i := 0; i < len(p.Projects); i++ {
- ts.addDoublingData(p.Projects[i].Type)
- projectData = append(projectData, p.Projects[i].Type)
- }
- doublingData = append(doublingData, projectData...)
- }
- delaySce := 0
- if ts.gameScene.RoundIndex == 2 {
- if len(ts.gameScene.Players[chair].Projects) > 0 {
- userservices.DoRecord(ts.gameScene.Players[chair].userID, userservices.Record_Project, 1)
- if ts.gameScene.Players[chair].Projects[0].Type >= PROJECT_FIFTY && ts.gameScene.Players[getFriendChair(chair)].isRobot {
- delaySce += 3500
- ts.sendRobotChatAction(RobotChatAction_FriendGetBigProject, ts.gameScene.Players[getFriendChair(chair)].userID, ts.gameScene.Players[chair].userID, delaySce)
- delaySce += 2500
- }
- if ts.gameScene.Players[chair].Projects[0].Type >= PROJECT_HUNDRED {
- start := rand.Intn(4)
- for i := 0; i < CHAIR_COUNT; i++ {
- chairId := (start + i) % CHAIR_COUNT
- if !isSameTeam(chairId, chair) && ts.gameScene.Players[chairId].isRobot {
- ts.sendRobotChatAction(RobotChatAction_EmenyGetBigProject, ts.gameScene.Players[chairId].userID, -1, delaySce)
- delaySce += 2500
- break
- }
- }
- }
- }
- }
- if ts.gameScene.FinalClub == Suit_Hokum && ts.gameScene.RoundType == CardType_Invalid &&
- getCardType(card) != ts.gameScene.TrumpType && !isBiggestCard(card, ts.gameScene.TrumpType) {
- if isScoreCard(card, []int{}, ts.gameScene.GameOutCardHistory, ts.gameScene.TrumpType) {
- p.IsCallBiggest = true
- }
- }
- if ts.gameScene.RoundType == CardType_Invalid {
- ts.gameScene.RoundType = getCardType(card)
- ts.simulator.roundType = ts.gameScene.RoundType
- if ts.roomInfo.IsCorrectionMode && len(ts.gameScene.Players[chair].HandCards) == NORMAL_HOLD_CARD-2 {
- ts.gameScene.CanCorrect = true
- }
- }
- ts.gameScene.GameOutCardHistory = append(ts.gameScene.GameOutCardHistory, card)
- if !ts.gameScene.isRoundEnd() {
- ts.gameScene.nextChair()
- if ts.gameScene.FinalClub == Suit_Hokum {
- isFriendCallBiggest := false
- friendOutCard := ts.gameScene.Players[getFriendChair(ts.gameScene.WhoseTurn)].CurrentCard
- if isValidCard(friendOutCard) {
- isFriendCallBiggest = ts.gameScene.Players[getFriendChair(ts.gameScene.WhoseTurn)].IsCallBiggest
- if isBiggestCard(friendOutCard, ts.gameScene.TrumpType) {
- isFriendCallBiggest = true
- }
- }
- bigCards := ts.simulator.getCanOutCards(ts.gameScene.WhoseTurn, isFriendCallBiggest)
- if !ts.roomInfo.IsCorrectionMode {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].initBigCards(bigCards)
- }
- ts.simulator.fakers[ts.gameScene.WhoseTurn].initBigCards(bigCards)
- }
- if len(doublingData) > 0 {
- ts.sendShowDoublingMsg(doublingData)
- }
- ts.resetGameTimer()
- ts.table.NotifySceneChanged(-1)
- return true, ""
- }
- ts.table.KillTimer(TIMER_GAME)
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.table.KillTimer(TIMER_ROBOT_SEND_CHAT_0 + i)
- }
- // 一圈打完了,需要延迟开新的一圈
- outCards := ts.gameScene.getRoundCards()
- winner := ts.logic.getWinner(outCards, ts.gameScene.RoundType)
- ts.table.LogWithTableId("end a round outCards = %s roundType = %d,winner = %d",
- getCardsHex(outCards), ts.gameScene.RoundType, winner)
- for i := 0; i < CHAIR_COUNT; i++ {
- if !isSameTeam(i, winner) {
- ts.gameScene.Players[i].consecutiveWinCardCount = 0
- ts.simulator.fakers[i].consecutiveWinCardCount = 0
- } else {
- ts.gameScene.Players[i].consecutiveWinCardCount++
- ts.simulator.fakers[i].consecutiveWinCardCount++
- }
- if i == winner {
- ts.gameScene.Players[i].selfConsecutiveWinCardCount = 0
- } else {
- ts.gameScene.Players[i].selfConsecutiveWinCardCount++
- }
- }
- if ts.gameScene.Players[winner].consecutiveWinCardCount >= 5 && ts.roomInfo.IsDoublingMode {
- ts.addDoublingData(Doubling_ConsecutiveWinOverFour)
- doublingData = append(doublingData, Doubling_ConsecutiveWinOverFour)
- start := rand.Intn(4)
- for i := 0; i < CHAIR_COUNT; i++ {
- chairId := (start + i) % CHAIR_COUNT
- if !isSameTeam(chairId, winner) && ts.gameScene.Players[chairId].isRobot && ts.gameScene.Players[winner].consecutiveWinCardCount == 5 {
- ts.sendRobotChatAction(RobotChatAction_LoseOverFive, ts.gameScene.Players[chairId].userID, -1, delaySce)
- delaySce += 2500
- break
- }
- }
- }
- if ts.gameScene.Players[winner].selfConsecutiveWinCardCount == 5 {
- if ts.gameScene.Players[winner].isRobot {
- ts.sendRobotChatAction(RobotChatAction_SelfWinOverFive, ts.gameScene.Players[winner].userID, -1, delaySce)
- delaySce += 2500
- }
- if ts.gameScene.Players[winner].isRobot && ts.gameScene.Players[getFriendChair(winner)].isRobot {
- ts.sendRobotChatAction(RobotChatAction_FriendWinOverFive, ts.gameScene.Players[getFriendChair(winner)].userID, -1, delaySce)
- }
- }
- winScore := ts.gameScene.endAOutCardRound(winner)
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, winner) {
- ts.simulator.fakers[i].addScore(winScore)
- }
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.simulator.gameOutCardHistory = append(ts.simulator.gameOutCardHistory, ts.simulator.fakers[i].currentCard)
- ts.simulator.fakers[i].currentCard = CARD_COUNT
- ts.gameScene.Players[i].initBigCards([]int{})
- ts.simulator.fakers[i].initBigCards([]int{})
- }
- if len(doublingData) > 0 {
- ts.sendShowDoublingMsg(doublingData)
- }
- ts.table.NotifySceneChanged(-1)
- if ts.gameScene.isGameEnd() {
- ts.table.SetTimer(TIMER_NEWROUND, 1800)
- } else {
- ts.table.SetTimer(TIMER_NEWROUND, SEC_NEWROUND)
- }
- return true, ""
- }
- func (ts *tablesink) onTimerNewRound() {
- if ts.gameScene.Phase == Phase_End {
- return
- }
- if ts.gameScene.isGameEnd() {
- if ts.roomInfo.IsCorrectionMode {
- ts.table.SetTimer(TIMER_CORRECTDELAY, SCE_CORRECT_DELAY)
- return
- }
- // 轮次结束也要清理收牌信息
- ts.gameScene.newOutCardRound()
- // 进入SetEnd阶段
- ts.enterGameEndPhase(true)
- return
- }
- // 继续
- ts.gameScene.newOutCardRound()
- if ts.gameScene.RoundIndex == 2 {
- for i := 0; i < CHAIR_COUNT; i++ {
- if len(ts.gameScene.Players[i].Projects) == 0 {
- continue
- }
- ts.simulator.fakers[i].projects = append(ts.simulator.fakers[i].projects, ts.gameScene.Players[i].Projects...)
- }
- }
- if !ts.roomInfo.IsCorrectionMode {
- ts.gameScene.checkCanGawah()
- }
- ts.simulator.roundType = ts.gameScene.RoundType
- ts.resetGameTimer()
- ts.gameScene.Index++
- ts.table.NotifySceneChanged(-1)
- }
- func (ts *tablesink) enterGameEndPhase(isCalc bool) {
- if isCalc {
- ts.gameScene.gameEnd()
- } else {
- ts.gameScene.PhaseIndex = 0
- ts.gameScene.Phase = Phase_GameEnd
- }
- if !ts.table.IsPrivate() && ts.roomInfo.LevelParam >= 100 {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].LevelValue = 0
- if ts.gameScene.Players[i].FinalCalcScore == 0 {
- continue
- }
- value := (10 * ts.roomInfo.LevelParam * ts.gameScene.Players[i].FinalCalcScore) / 100
- value = ts.table.AddExperience(ts.gameScene.Players[i].userID, value)
- ts.gameScene.Players[i].LevelValue = value
- }
- }
- var scores perRoundScores
- scores.positionScore0 = ts.gameScene.Players[0].FinalCalcScore
- scores.positionScore1 = ts.gameScene.Players[1].FinalCalcScore
- ts.gameScene.scoreHistory = append(ts.gameScene.scoreHistory, scores)
- goal := -1
- if scores.positionScore0 == 0 {
- goal = 1
- } else if scores.positionScore1 == 0 {
- goal = 1
- }
- if goal != -1 {
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, goal) {
- userservices.DoRecord(ts.gameScene.Players[i].userID, userservices.Record_BalootWinAllScore, 1)
- }
- }
- }
- ts.statisticsRobotAction()
- ts.gameScene.statics = append(ts.gameScene.statics, robotChatActionList{
- round: ts.gameScene.GameIndex,
- action: ts.gameScene.robotChatList,
- })
- ts.gameScene.robotChatList = []robotChatAction{}
- ts.gameScene.robotSendChatCount = 0
- ts.resetGameTimer()
- ts.reportTaskAndUpdateGameScore()
- //ts.table.NotifySceneChanged(-1)
- if !ts.gameScene.isGameFinish() && !ts.surrenderInfo.isSurrenderEnd() {
- ts.table.SendGameData(-1, CMD_SMALL_RESULT, ts.gameScene.getScene(-1, true, false))
- }
- // 为比赛场服务,最后一局EndScore不清零
- if (ts.gameScene.ScoreToWin < -1 && (ts.gameScene.GameIndex+ts.gameScene.ScoreToWin) < -1) ||
- (!ts.table.IsPrivate() && ts.gameScene.ScoreToWin == -1) {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].EndScore = 0
- }
- }
- if ts.gameScene.ScoreToWin < -1 && (ts.gameScene.GameIndex+ts.gameScene.ScoreToWin) < -1 && ts.table.GetOwner() == -1 {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].Doublings = []DoublingDetail{}
- ts.gameScene.Players[i].TotalScore = 0
- }
- }
- }
- func (ts *tablesink) reportTaskAndUpdateGameScore() {
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- score := 0
- // 比赛场,需要按玩家底分来上报分数,注意上报是本局变化的分数
- if ts.table.GetOwner() == -1 {
- oldScore := usr.GetScore()
- ts.table.LogWithTableId("reportTaskAndUpdateGameScore,%d,%d,%d", oldScore, usr.GetBaseScore(), usr.GetSetCount())
- // 上报完成后,修改自身分数
- score = ts.gameScene.getDoublingTotalTimes() * usr.GetBaseScore()
- if ts.gameScene.Players[i].FinalCalcScore < ts.gameScene.Players[getNextChair(i)].FinalCalcScore {
- score = -score
- } else if ts.gameScene.Players[i].FinalCalcScore == ts.gameScene.Players[getNextChair(i)].FinalCalcScore {
- if !isSameTeam(i, ts.gameScene.BuyChair) {
- score = -score
- }
- }
- usr.SetScore(oldScore + score)
- ts.table.UpdateGameScore(usr.GetUserId(), score)
- ts.gameScene.Players[i].EndScore = score
- ts.gameScene.Players[i].MatchScore += score
- } else {
- if !ts.table.IsPrivate() && ts.gameScene.ScoreToWin == -1 {
- score = ts.gameScene.getDoublingTotalTimes() * ts.gameScene.Players[i].bet
- if !ts.gameScene.isPlayerWinInQuickGame(i) {
- score = -score
- }
- ts.gameScene.Players[i].EndScore = score + ts.gameScene.Players[i].bet
- }
- ts.table.UpdateGameScore(usr.GetUserId(), ts.gameScene.Players[i].getTotalScore())
- }
- if ts.table.IsPrivate() && config.Server.IsLadderRoom > 0 {
- p := &ts.gameScene.Players[i]
- ts.gameScene.Players[i].LastWinCount = ladder.GetUserConsecutiveWinCount(p.userID, GAMEID)
- ts.gameScene.Players[i].LadderChangeValue, _ = ladder.AddUserLadderScore(p.userID, GAMEID, ts.roomInfo.RoomName, score)
- if ts.gameScene.Players[i].LadderChangeValue > 0 {
- ts.gameScene.Players[i].LastWinCount++
- }
- d := ladder.GetUserLadderInfo(p.userID, GAMEID)
- if d != nil {
- ts.gameScene.Players[i].LadderInfo = *d
- } else {
- ts.table.LogWithTableId("User:%d, LadderInfo is nil", p.userID)
- }
- }
- if ts.gameScene.FinalClub == Suit_Sun {
- task.DoTaskAction(usr.GetUserId(), TaskAction_Baloot_Sun, 1, task.TaskScope{GameName: GAME_NAME})
- }
- if ts.gameScene.Players[i].TotalChangeScore >= 80 {
- task.DoTaskAction(usr.GetUserId(), TaskAction_Baloot80, 1, task.TaskScope{GameName: GAME_NAME})
- }
- if ts.gameScene.Players[i].TotalChangeScore >= 100 {
- task.DoTaskAction(usr.GetUserId(), TaskAction_Baloot100, 1, task.TaskScope{GameName: GAME_NAME})
- }
- if ts.gameScene.Players[i].TotalChangeScore >= 120 {
- task.DoTaskAction(usr.GetUserId(), TaskAction_Baloot120, 1, task.TaskScope{GameName: GAME_NAME})
- }
- }
- }
- func (ts *tablesink) enterEndPhase() {
- // 结算
- winners := ts.gameScene.getWinner()
- ts.table.LogWithTableId("tablesink.enterEndPhase getWinners:%v", winners)
- if len(winners) == 0 {
- ts.table.LogWithTableId("tablesink.enterEndPhase getWinners = 0")
- if ts.table.IsPrivate() {
- ts.table.PrivateRoomSetWinners([]int{})
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- return
- }
- totalBet := 0
- if ts.gameScene.Players[winners[0]].bet > 0 {
- totalBet = ts.gameScene.getTotalBet(winners[0])
- }
- // 平分
- endScore := totalBet / len(winners)
- if endScore != 0 {
- for _, v := range winners {
- ts.gameScene.Players[v].EndScore = endScore
- }
- }
- // 写分
- for i := 0; i < CHAIR_COUNT; i++ {
- p := &ts.gameScene.Players[i]
- usr := ts.table.GetUserByChair(i)
- if !p.IsValid || usr == nil {
- continue
- }
- realWin := p.EndScore - p.bet
- if p.bet == 0 {
- realWin = 0
- }
- tax := 0
- if realWin > 0 {
- tax = realWin * ts.roomInfo.TaxRate / 100
- }
- wScore := p.EndScore - tax
- if p.bet == 0 {
- wScore = 0
- }
- ts.writeScore(p.userID, wScore, tax, 0, ScoreType_End, ts.roomInfo.RoomName, p.isRobot)
- if wScore > 0 {
- userservices.DoRecord(p.userID, userservices.Record_MaxWin, wScore)
- }
- if !p.isRobot {
- roomType := waterpool.RoomType_Normal
- if ts.roomInfo.IsDoublingMode {
- roomType = waterpool.RoomType_Doubling
- }
- if ts.roomInfo.RoomType == 3 {
- roomType = waterpool.RoomType_Quick
- }
- if config.Server.IsLadderRoom > 0 {
- roomType = waterpool.RoomType_Ladder
- }
- if p.isControl {
- go waterpool.UpdataUserWaterPool(p.userID, realWin, GAME_NAME, roomType, ts.roomInfo.RoomID)
- } else {
- go waterpool.ReduceInventoryValue(GAMEID, ts.roomInfo.RoomName, realWin-tax, roomType)
- }
- }
- // 写记录
- if ts.table.IsPrivate() {
- } else {
- if p.bet != 0 {
- go ts.table.WriteBetRecordWithSetcount(p.userID, p.bet, wScore, 1.0, "normal",
- fmt.Sprintf("totalpoits:[%v]", p.roundScores), ts.roomInfo.RoomName, len(p.roundScores))
- }
- if config.Server.IsLadderRoom > 0 {
- ts.gameScene.Players[i].LastWinCount = ladder.GetUserConsecutiveWinCount(p.userID, GAMEID)
- ts.gameScene.Players[i].LadderChangeValue, _ = ladder.AddUserLadderScore(p.userID, GAMEID, ts.roomInfo.RoomName, wScore-p.bet)
- if ts.gameScene.Players[i].LadderChangeValue > 0 {
- ts.gameScene.Players[i].LastWinCount++
- }
- d := ladder.GetUserLadderInfo(p.userID, GAMEID)
- if d != nil {
- ts.gameScene.Players[i].LadderInfo = *d
- } else {
- ts.table.LogWithTableId("User:%d, LadderInfo is nil", p.userID)
- }
- }
- }
- }
- if ts.roomInfo.RoomID == 0 && !ts.table.IsPrivate() {
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.gameScene.Players[i].LevelValue = 0
- if ts.gameScene.Players[i].isRobot {
- continue
- }
- value := ts.table.AddExperience(ts.gameScene.Players[i].userID, 100)
- ts.gameScene.Players[i].LevelValue = value
- }
- }
- ts.gameScene.Phase = Phase_End
- ts.table.NotifySceneChanged(-1)
- if ts.table.IsPrivate() {
- winnerUsers := make([]int, len(winners))
- for i := 0; i < len(winners); i++ {
- winnerUsers[i] = ts.gameScene.Players[winners[i]].userID
- }
- ts.table.PrivateRoomSetWinners(winnerUsers)
- ts.writePrivateBetRecords()
- }
- ts.endGame()
- ts.uniqueId = uuid.New().String()
- ts.gameScene.initData(ts.table.GetTableID(), ts.roomInfo.ScoreToWin, ts.roomInfo.MaxSurrenderCount)
- }
- func (ts *tablesink) writePrivateBetRecords() {
- for i := 0; i < CHAIR_COUNT; i++ {
- p := &ts.gameScene.Players[i]
- usr := ts.table.GetUserByChair(i)
- if !p.IsValid || usr == nil {
- continue
- }
- fee, prize := ts.table.PrivateRoomGetFeeAndPrize(p.userID)
- ts.table.LogWithTableId("writePrivateBetRecords user[%d] fee[%d],prize[%d]", p.userID, fee, prize)
- ts.table.WriteBetRecordWithSetcount(p.userID, fee, prize, 1.0, ts.roomType,
- fmt.Sprintf("totalpoits:%v", p.roundScores), ts.roomInfo.RoomName, len(p.roundScores))
- }
- }
- func (ts *tablesink) endGame() {
- ts.table.LogWithTableId("--------endGame-----------")
- ts.gameScene.dump(true)
- ts.statisticsScoreHistoryToExcel()
- ts.statisRobotChatCount()
- ts.gameScene.PhaseIndex = 0
- ts.gameScene.GameIndex = 0
- ts.gameScene.Index = 0
- ts.surrenderInfo.isSurrendering = false
- ts.table.KillAllTimer()
- if ts.table.IsPrivate() {
- ts.table.SetTimer(TIMER_DELAY_END, 1000)
- // 私人场,不继续下一把
- if ts.roomInfo.BaseScore == 0 {
- ts.gameScene.pointsToEndScore()
- }
- return
- }
- ts.table.EndGame()
- //realUserCount := 0
- robotCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- // 机器人,随机3-5秒准备
- if !usr.IsRobot() {
- ts.table.SetTimer(TIMER_READY_0+i, SEC_READY)
- ts.gameScene.Players[i].isEndToStart = true
- //realUserCount++
- } else {
- //ts.table.SetTimer(TIMER_READY_0+i, 100)
- robotCount++
- }
- }
- if robotCount > 0 {
- ts.table.SetTimer(TIMER_REMOVE_ROBOT, 1000+rand.Intn(1000))
- }
- }
- func (ts *tablesink) writeScore(userId int, amount, tax int, status, scoreType int, sourceName string, isRobot bool) (bool, int) {
- return ts.table.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName)
- }
- func (ts *tablesink) checkIsNeedRobot() {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- fmt.Print("游戏阶段=====ts.gameScene.Phase",ts.gameScene.Phase)
- return
- }
- if ts.roomInfo.RobotCount == 0 {
- fmt.Print("游戏阶段=====ts.roomInfo.RobotCount",ts.roomInfo.RobotCount)
- return
- }
- if ts.table.IsPrivate() {
- fmt.Print("游戏阶段=====ts.table.IsPrivate")
- return
- }
- count := 0
- playerCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- if !usr.IsRobot() {
- playerCount++
- }
- if usr.GetUserStatus() <= user.UserStatus_Free {
- continue
- }
- count++
- }
- chairCount := CHAIR_COUNT
- if count >= chairCount {
- fmt.Print("游戏阶段=====玩家数大于椅子数=====")
- return
- }
- robotCount := chairCount - count
- ts.table.LogWithTableId("-------checkIsNeedRobot. need: %d ------", robotCount)
- if robotCount > 0 && playerCount > 0 {
- sec := ts.roomInfo.RobotEnterRoomTime*1000 - 500
- time.AfterFunc(time.Duration(sec)*time.Millisecond, func() {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- fmt.Print("游戏阶段=====ts.gameScene.Phase",ts.gameScene.Phase)
- return
- }
- tableID := ts.table.GetTableID()
- robotmanager.GetOneRobotEnterTable(tableID, ts.roomInfo.MinGold, ts.roomInfo.MaxGold)
- })
- }
- }
- func (ts *tablesink) removeOneRobot() {
- if ts.gameScene.Phase != Phase_End && ts.gameScene.Phase != Phase_Free {
- return
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- if !usr.IsRobot() {
- continue
- }
- ts.table.KickUserByChair(i, false)
- //return
- }
- }
- func (ts *tablesink) getRobotActionTime(chairId int, isNeedDiminishing bool) int {
- if ts.gameScene.Phase == Phase_FirstBuy || ts.gameScene.Phase == Phase_SecondBuy {
- return 1000 + rand.Intn(2000)
- }
- if !isNeedDiminishing {
- diff := ts.roomInfo.MaxRobotNotFirstOutMS - ts.roomInfo.MinRobotNotFirstOutMS
- if diff <= 0 {
- diff = MS_MaxRobotNotFirstOut - MS_MinRobotNotFirstOut
- }
- minMs := ts.roomInfo.MinRobotNotFirstOutMS
- if minMs < MIN_OUT_MS {
- minMs = MS_MinRobotNotFirstOut
- }
- return minMs + rand.Intn(diff)
- }
- ms := 0
- if ts.gameScene.getRoundOutedPlayerCount() > 0 {
- diff := ts.roomInfo.MaxRobotNotFirstOutMS - ts.roomInfo.MinRobotNotFirstOutMS
- if diff <= 0 {
- diff = MS_MaxRobotNotFirstOut - MS_MinRobotNotFirstOut
- }
- minMs := ts.roomInfo.MinRobotNotFirstOutMS
- if minMs <= MIN_OUT_MS {
- minMs = MS_MinRobotNotFirstOut
- }
- leftCardCount := NORMAL_HOLD_CARD - len(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards)
- deMs := ts.roomInfo.DiminishingNotFirstOutMS * leftCardCount
- if deMs <= 0 || (minMs-deMs) < MIN_OUT_MS {
- deMs = MS_DiminishingNotFirstOut * leftCardCount
- }
- ms = minMs + rand.Intn(diff) - deMs
- } else {
- diff := ts.roomInfo.MaxRobotFirstOutMS - ts.roomInfo.MinRobotFirstOutMS
- if diff <= 0 {
- diff = MS_MaxRobotFirstOut - MS_MinRobotFirstOut
- }
- minMs := ts.roomInfo.MinRobotFirstOutMS
- if minMs < MIN_OUT_MS {
- minMs = MS_MinRobotFirstOut
- }
- leftCardCount := NORMAL_HOLD_CARD - len(ts.gameScene.Players[ts.gameScene.WhoseTurn].HandCards)
- deMs := ts.roomInfo.DiminishingFirstOutMS * leftCardCount
- if deMs <= 0 || (minMs-deMs) < MIN_OUT_MS {
- deMs = MS_DiminishingFirstOut * leftCardCount
- }
- ms = minMs + rand.Intn(diff) - deMs
- }
- return ms
- }
- func (ts *tablesink) checkRobotAction() {
- if ts.gameScene.Phase == Phase_GameEnd || ts.gameScene.Phase == Phase_Start {
- return
- }
- if ts.gameScene.Phase == Phase_Reshuffle {
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil || !usr.IsRobot() {
- continue
- }
- if ts.gameScene.Players[i].canReshuffle() {
- ms := rand.Intn(500) + 500
- ts.table.SetTimer(TIMER_ROBOT_ACTION_0+i, ms)
- break
- }
- }
- return
- }
- if ts.gameScene.WhoseTurn != -1 {
- usr := ts.table.GetUserByChair(ts.gameScene.WhoseTurn)
- if usr == nil || !usr.IsRobot() {
- return
- }
- ms := ts.getRobotActionTime(ts.gameScene.WhoseTurn, ts.gameScene.Phase == Phase_Play)
- ts.table.SetTimer(TIMER_ROBOT_ACTION_0+ts.gameScene.WhoseTurn, ms)
- } else {
- start := rand.Intn(CHAIR_COUNT)
- ms := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- iChair := (i + start) % CHAIR_COUNT
- usr := ts.table.GetUserByChair(iChair)
- if usr == nil || !usr.IsRobot() || !ts.gameScene.Players[iChair].canAction() {
- continue
- }
- if ms == 0 {
- ms = ts.getRobotActionTime(iChair, false)
- } else {
- ms += 1000
- }
- ts.table.SetTimer(TIMER_ROBOT_ACTION_0+iChair, ms)
- }
- }
- }
- func (ts *tablesink) onTimerAutoAction(chairId int) {
- if ts.gameScene.WhoseTurn != -1 && ts.gameScene.Phase != Phase_Reshuffle {
- ts.table.LogWithTableId("tablesink.onTimerAutoAction WhoseTurn != -1")
- return
- }
- if !ts.gameScene.Players[chairId].AutoOut {
- ts.table.LogWithTableId("tablesink.onTimerAutoAction not Auto")
- return
- }
- if ts.gameScene.Phase != Phase_FirstBuy &&
- ts.gameScene.Phase != Phase_SecondBuy &&
- ts.gameScene.Phase != Phase_Double &&
- ts.gameScene.Phase != Phase_Reshuffle {
- ts.table.LogWithTableId("tablesink.onTimerAutoAction not Correct Phase")
- return
- }
- if ts.gameScene.Phase == Phase_Reshuffle {
- ts.dealReshuffle(chairId, Reshuffle_Pass)
- return
- }
- action := ts.gameScene.Players[chairId].getAutoBuyAction()
- if action != Action_Buy_Invaild && ts.gameScene.Players[chairId].canAction() {
- if ts.gameScene.Phase == Phase_Double {
- ts.dealDouble(chairId, action)
- }
- if ts.gameScene.Phase == Phase_FirstBuy || ts.gameScene.Phase == Phase_SecondBuy {
- ts.dealBuy(chairId, action)
- }
- }
- }
- func (ts *tablesink) onTimerRobotAction(chairId int) {
- if ts.gameScene.WhoseTurn != -1 {
- if ts.gameScene.WhoseTurn != chairId && ts.gameScene.Phase != Phase_Reshuffle {
- ts.table.LogWithTableId("tablesink.robotAction whoseturn changed")
- return
- }
- } else {
- if !ts.gameScene.Players[chairId].canAction() {
- ts.table.LogWithTableId("tablesink.robotAction canAction changed")
- return
- }
- }
- if ts.gameScene.Phase == Phase_Play {
- if len(ts.gameScene.Players[chairId].HandCards) == 0 {
- ts.table.LogWithTableId("tablesink.robotAction chair:%d HandCard == 0", chairId)
- return
- }
- var projects []int
- if ts.gameScene.RoundIndex == 1 {
- cardList := make([]int, len(ts.gameScene.Players[chairId].HandCards))
- copy(cardList, ts.gameScene.Players[chairId].HandCards)
- projects = ts.logic.getBestProject(cardList)
- }
- if ts.gameScene.Players[chairId].CanGawah {
- ts.dealGawah()
- return
- }
- outCard := CARD_COUNT
- isQuickOrLadder := false
- if ts.roomInfo.RoomType == 3 || config.Server.IsLadderRoom == 1 {
- isQuickOrLadder = true
- }
- outCard = ts.simulator.getBestOutCard(chairId, isQuickOrLadder)
- if !isValidCard(outCard) {
- if len(ts.gameScene.Players[chairId].BigCards) > 0 {
- outCard = ts.gameScene.Players[chairId].BigCards[0]
- } else {
- outCard = ts.logic.worstCard(ts.gameScene.Players[chairId].HandCards, ts.gameScene.RoundType)
- }
- }
- ts.dealOutCard(outCard, projects)
- } else {
- action := ts.getAction(chairId)
- switch ts.gameScene.Phase {
- case Phase_FirstBuy:
- fallthrough
- case Phase_SecondBuy:
- if ts.roomInfo.RoomID == 0 && !ts.table.IsPrivate() {
- action = Action_Buy_Pass
- if ts.allPassCount >= 2 {
- action = Action_Buy_Sun
- }
- }
- ts.dealBuy(chairId, action)
- case Phase_ChooseTrump:
- ts.dealChooseTrump(action)
- case Phase_CloseOpen:
- ts.dealCloseOrOpen(action)
- case Phase_Double:
- ts.dealDouble(chairId, action)
- case Phase_Reshuffle:
- if ts.gameScene.Players[chairId].ReshuffleAction == Reshuffle_None && ts.gameScene.Players[chairId].CanDoReshuffle {
- ts.dealReshuffle(chairId, Reshuffle_Confirm)
- }
- default:
- ts.table.LogWithTableId("tablesink.robotAction invalid phase %d", ts.gameScene.Phase)
- }
- }
- }
- func (ts *tablesink) getAction(chairId int) int {
- buyWinScore := 0
- action, optionButtons := ts.getInitActionAndOperationList(chairId)
- // 不抢自己队友的买牌
- if isValidChair(ts.gameScene.BuyChair) && isFriendChair(ts.gameScene.BuyChair, chairId) &&
- (ts.gameScene.Phase == Phase_FirstBuy || ts.gameScene.Phase == Phase_SecondBuy) {
- return action
- }
- // 做模拟场景分析,并获取最大赢分的操作
- for i := 0; i < len(optionButtons); i++ {
- // 过滤掉Action_Buy_Pass的解析
- if optionButtons[i] == Action_Buy_Pass &&
- ts.gameScene.Phase != Phase_ChooseTrump &&
- ts.gameScene.Phase != Phase_CloseOpen {
- continue
- }
- trumpType := CardType_Invalid
- suit := Suit_Hokum
- baseTimes := 1
- isBo1 := false
- isClose := false
- score := -1000
- switch ts.gameScene.Phase {
- case Phase_FirstBuy:
- if optionButtons[i] == Action_Buy_Hokum || optionButtons[i] == Action_Buy_ConfirmHokum {
- trumpType = getCardType(ts.gameScene.PublicCard)
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious && optionButtons[i] == Action_Buy_Hokum {
- sortedCards := sortCards(ts.gameScene.Players[chairId].HandCards)
- if len(sortedCards[trumpType]) >= 2 {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- ts.gameScene.Players[chairId].robotActionType = ts.gameScene.Players[chairId].robotType
- return Action_Buy_Hokum
- } else {
- return action
- }
- }
- }
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious &&
- optionButtons[i] == Action_Buy_ConfirmHokum &&
- ts.gameScene.Players[chairId].robotActionType != RobotType_Cautious {
- return Action_Buy_ConfirmHokum
- }
- } else if optionButtons[i] == Action_Buy_Ashkal {
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious {
- totalPoint := 0
- for j := 0; j < len(ts.gameScene.Players[chairId].HandCards); j++ {
- totalPoint += getCardPoint(ts.gameScene.Players[chairId].HandCards[j], CardType_Invalid)
- }
- if totalPoint >= 25 {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- return Action_Buy_Ashkal
- } else {
- return action
- }
- }
- }
- suit = Suit_Ashkal
- } else {
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious {
- totalPoint := 0
- for j := 0; j < len(ts.gameScene.Players[chairId].HandCards); j++ {
- totalPoint += getCardPoint(ts.gameScene.Players[chairId].HandCards[j], CardType_Invalid)
- }
- if totalPoint >= 22 && getCardPoint(ts.gameScene.PublicCard, CardType_Invalid) >= 3 {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- return optionButtons[i]
- } else {
- return action
- }
- }
- }
- suit = Suit_Sun
- }
- case Phase_SecondBuy:
- if optionButtons[i] == Action_Buy_Hokum || optionButtons[i] == Action_Buy_ConfirmHokum {
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious && optionButtons[i] == Action_Buy_Hokum {
- t := getLAGsBestTrumpType(ts.gameScene.Players[chairId].HandCards, ts.gameScene.PublicCard)
- if t != CardType_Invalid {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- ts.gameScene.Players[chairId].robotActionType = ts.gameScene.Players[chairId].robotType
- return Action_Buy_Hokum
- } else {
- return action
- }
- }
- }
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious &&
- optionButtons[i] == Action_Buy_ConfirmHokum &&
- ts.gameScene.Players[chairId].robotActionType != RobotType_Cautious {
- return Action_Buy_ConfirmHokum
- }
- for n := CardType_Diamond; n <= CardType_Spade; n++ {
- if n == getCardType(ts.gameScene.PublicCard) {
- continue
- }
- maxScore := ts.getSimulatorSceneBuyWinScore(n, suit, chairId, baseTimes, isBo1, isClose)
- if maxScore > score {
- score = maxScore
- trumpType = n
- }
- }
- } else if optionButtons[i] == Action_Buy_Ashkal {
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious {
- totalPoint := 0
- for j := 0; j < len(ts.gameScene.Players[chairId].HandCards); j++ {
- totalPoint += getCardPoint(ts.gameScene.Players[chairId].HandCards[j], CardType_Invalid)
- }
- if totalPoint >= 25 {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- return optionButtons[i]
- } else {
- return action
- }
- }
- }
- suit = Suit_Ashkal
- } else {
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious {
- totalPoint := 0
- for j := 0; j < len(ts.gameScene.Players[chairId].HandCards); j++ {
- totalPoint += getCardPoint(ts.gameScene.Players[chairId].HandCards[j], CardType_Invalid)
- }
- if totalPoint >= 22 && getCardPoint(ts.gameScene.PublicCard, CardType_Invalid) >= 3 {
- r := rand.Intn(100)
- if r < ts.gameScene.Players[chairId].robotType*50 {
- return optionButtons[i]
- } else {
- return action
- }
- }
- }
- suit = Suit_Sun
- }
- case Phase_Double:
- trumpType = ts.gameScene.TrumpType
- suit = ts.gameScene.FinalClub
- baseTimes = optionButtons[i] - Action_Buy_Double + 2
- if optionButtons[i] == Action_Buy_Coffee {
- baseTimes = 1
- isBo1 = true
- }
- case Phase_CloseOpen:
- isClose = (optionButtons[i] == Action_Buy_Close)
- trumpType = ts.gameScene.TrumpType
- case Phase_ChooseTrump:
- if ts.gameScene.Players[chairId].robotType != RobotType_Cautious &&
- ts.gameScene.Players[chairId].robotActionType != RobotType_Cautious {
- return getLAGsBestTrumpType(ts.gameScene.Players[chairId].HandCards, ts.gameScene.PublicCard)
- }
- trumpType = optionButtons[i]
- }
- score = ts.getSimulatorSceneBuyWinScore(trumpType, suit, chairId, baseTimes, isBo1, isClose)
- if baseTimes >= 2 {
- score = score / baseTimes
- }
- if score >= buyWinScore {
- buyWinScore = score
- if ts.gameScene.Phase == Phase_FirstBuy || ts.gameScene.Phase == Phase_SecondBuy {
- // 这里是避免机器人买牌过于频繁
- if buyWinScore >= 10 {
- action = optionButtons[i]
- }
- } else if ts.gameScene.Phase == Phase_Double {
- if buyWinScore >= 30 {
- action = optionButtons[i]
- }
- } else {
- action = optionButtons[i]
- }
- }
- }
- return action
- }
- func (ts *tablesink) getInitActionAndOperationList(chairId int) (int, []int) {
- optionButtons := []int{}
- action := 0
- switch ts.gameScene.Phase {
- case Phase_FirstBuy:
- fallthrough
- case Phase_SecondBuy:
- action = Action_Buy_Pass
- optionButtons = ts.gameScene.Players[chairId].CanAction
- if !ts.gameScene.Players[chairId].canDoBuyAction(Action_Buy_Pass) {
- action = ts.gameScene.Players[chairId].getAutoBuyAction()
- }
- case Phase_Double:
- optionButtons = ts.gameScene.Players[chairId].CanAction
- action = Action_Buy_Pass
- case Phase_CloseOpen:
- optionButtons = append(optionButtons, Action_Buy_Close, Action_Buy_Open)
- action = Action_Buy_Open
- case Phase_ChooseTrump:
- for i := CardType_Diamond; i <= CardType_Spade; i++ {
- if i == getCardType(ts.gameScene.PublicCard) {
- continue
- }
- optionButtons = append(optionButtons, i)
- }
- cardList := make([]int, len(ts.gameScene.Players[chairId].HandCards))
- copy(cardList, ts.gameScene.Players[chairId].HandCards)
- cardList = append(cardList, ts.gameScene.PublicCard)
- currentCardIndex := ts.logic.currentCardIndex
- for j := 0; j < CHAIR_COUNT; j++ {
- if j == chairId {
- leftCards := ts.logic.getLeftCards(true)
- cardList = append(cardList, leftCards...)
- break
- }
- ts.logic.currentCardIndex += SURPLUS_SEND_CARD
- }
- ts.logic.currentCardIndex = currentCardIndex
- action = getBestTrumpType(cardList, ts.gameScene.PublicCard)
- }
- return action, optionButtons
- }
- func (ts *tablesink) getSimulatorSceneBuyWinScore(trumpType, suit, chairId, baseTimes int, isBo1, isClose bool) int {
- getPublicCardChairId := chairId
- if suit == Suit_Ashkal {
- getPublicCardChairId = getFriendChair(chairId)
- }
- ss := newSimulatorScene()
- ss.initData(trumpType, suit, chairId, baseTimes, isBo1, isClose)
- currentCardIndex := ts.logic.currentCardIndex
- for j := 0; j < CHAIR_COUNT; j++ {
- leftCards := ts.logic.getLeftCards(getPublicCardChairId == j)
- ss.fakers[j].handCards = append(ss.fakers[j].handCards, ts.gameScene.Players[j].HandCards...)
- ss.fakers[j].handCards = append(ss.fakers[j].handCards, leftCards...)
- if getPublicCardChairId == j {
- ss.fakers[j].handCards = append(ss.fakers[j].handCards, ts.gameScene.PublicCard)
- }
- f := &ss.fakers[j]
- sort.Slice(f.handCards, func(m, n int) bool {
- return getCardSortValue(f.handCards[m], trumpType) < getCardSortValue(f.handCards[n], trumpType)
- })
- }
- ts.logic.currentCardIndex = currentCardIndex
- isQuickOrLadder := false
- if ts.roomInfo.RoomType == 3 || config.Server.IsLadderRoom == 1 {
- isQuickOrLadder = true
- }
- ss.startSimulatorScene(getPreviousChair(ts.gameScene.Banker), isQuickOrLadder)
- buyWinScore := ss.buyWinScore
- if ss.suit != Suit_Hokum {
- buyWinScore /= 2
- }
- if !ss.isWinScoreBigThanFriend() {
- buyWinScore = -1
- }
- return buyWinScore
- }
- func (ts *tablesink) updateRobotChatAction(action int) {
- bFound := false
- for i := 0; i < len(ts.gameScene.robotChatList); i++ {
- if ts.gameScene.robotChatList[i].chatType == action {
- bFound = true
- ts.gameScene.robotChatList[i].count++
- }
- }
- if !bFound {
- ts.gameScene.robotChatList = append(ts.gameScene.robotChatList, robotChatAction{count: 1, chatType: action})
- }
- }
- func (ts *tablesink) sendRobotChatAction(action, sender, receiver, delaySec int) {
- if ts.gameScene.robotSendChatCount >= ts.gameScene.robotSendChatMaxCount {
- return
- }
- if ts.roomInfo.ScoreToWin == 1 && ts.gameScene.robotSendChatCount >= (ts.gameScene.RoundIndex/4+1)*2 {
- return
- }
- if ts.roomInfo.ScoreToWin != 1 && ts.gameScene.robotSendChatCount >= ts.gameScene.GameIndex+1 {
- return
- }
- if ts.roomInfo.ScoreToWin != 1 {
- if ts.gameScene.isSendChat {
- return
- }
- ts.gameScene.isSendChat = true
- }
- usr := ts.table.GetUserByUserId(sender)
- if usr == nil {
- return
- }
- if !usr.IsRobot() {
- return
- }
- timer := time.NewTimer(time.Duration(delaySec) * time.Millisecond)
- go func() {
- <-timer.C
- ts.updateRobotChatAction(action)
- userIndex := usr.GetUserIndex()
- var data string
- switch action {
- case RobotChatAction_MuiltyTimeOut:
- data = fmt.Sprintf("1/7/%d", sender)
- case RobotChatAction_LoseOverFive:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/5/%d", sender)
- } else {
- data = fmt.Sprintf("2/7/%d", sender)
- }
- case RobotChatAction_LoseOverEighty:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/5/%d", sender)
- } else {
- data = fmt.Sprintf("2/8/%d", sender)
- }
- case RobotChatAction_FriendGetBigProject:
- r := rand.Intn(90)
- if r < 30 {
- chatIds := []int{1, 6, 7}
- chatId := chatIds[rand.Intn(3)]
- data = fmt.Sprintf("3/%d/%d/%d", chatId, sender, receiver)
- } else if r < 60 && r >= 30 {
- data = fmt.Sprintf("1/9/%d", sender)
- } else {
- chatIds := []int{0, 3, 15}
- chatId := chatIds[rand.Intn(3)]
- data = fmt.Sprintf("2/%d/%d", chatId, usr.GetUserId())
- }
- case RobotChatAction_SelfWinOverFive:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/8/%d", sender)
- } else {
- chatIds := []int{16, 17}
- chatId := chatIds[rand.Intn(2)]
- data = fmt.Sprintf("2/%d/%d", chatId, sender)
- }
- case RobotChatAction_GoodHandCard:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/9/%d", sender)
- } else {
- chatIds := []int{0, 16, 12, 6}
- chatId := chatIds[rand.Intn(4)]
- data = fmt.Sprintf("2/%d/%d", chatId, sender)
- }
- case RobotChatAction_BadHandCard:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/5/%d", sender)
- } else {
- chatIds := []int{1, 5, 8}
- chatId := chatIds[rand.Intn(3)]
- data = fmt.Sprintf("2/%d/%d", chatId, sender)
- }
- case RobotChatAction_EmenyGetBigProject:
- r := rand.Intn(100)
- if r < 50 {
- data = fmt.Sprintf("1/5/%d", sender)
- } else {
- chatIds := []int{8, 14, 2}
- chatId := chatIds[rand.Intn(3)]
- data = fmt.Sprintf("2/%d/%d", chatId, sender)
- }
- case RobotChatAction_EnterRoom:
- data = fmt.Sprintf("1/0/%d", sender)
- case RobotChatAction_Reply:
- data = fmt.Sprintf("1/1/%d", sender)
- case RobotChatAction_FriendWinOverFive:
- data = fmt.Sprintf("1/2/%d", sender)
- }
- ts.recvChatMsg(userIndex, data)
- ts.gameScene.robotSendChatCount++
- timer.Stop()
- }()
- }
|