diff --git a/api/checkers/checkers/stored_game.pulsar.go b/api/checkers/checkers/stored_game.pulsar.go index da0c515..0141235 100644 --- a/api/checkers/checkers/stored_game.pulsar.go +++ b/api/checkers/checkers/stored_game.pulsar.go @@ -13,12 +13,13 @@ import ( ) var ( - md_StoredGame protoreflect.MessageDescriptor - fd_StoredGame_index protoreflect.FieldDescriptor - fd_StoredGame_board protoreflect.FieldDescriptor - fd_StoredGame_turn protoreflect.FieldDescriptor - fd_StoredGame_black protoreflect.FieldDescriptor - fd_StoredGame_red protoreflect.FieldDescriptor + md_StoredGame protoreflect.MessageDescriptor + fd_StoredGame_index protoreflect.FieldDescriptor + fd_StoredGame_board protoreflect.FieldDescriptor + fd_StoredGame_turn protoreflect.FieldDescriptor + fd_StoredGame_black protoreflect.FieldDescriptor + fd_StoredGame_red protoreflect.FieldDescriptor + fd_StoredGame_winner protoreflect.FieldDescriptor ) func init() { @@ -29,6 +30,7 @@ func init() { fd_StoredGame_turn = md_StoredGame.Fields().ByName("turn") fd_StoredGame_black = md_StoredGame.Fields().ByName("black") fd_StoredGame_red = md_StoredGame.Fields().ByName("red") + fd_StoredGame_winner = md_StoredGame.Fields().ByName("winner") } var _ protoreflect.Message = (*fastReflection_StoredGame)(nil) @@ -126,6 +128,12 @@ func (x *fastReflection_StoredGame) Range(f func(protoreflect.FieldDescriptor, p return } } + if x.Winner != "" { + value := protoreflect.ValueOfString(x.Winner) + if !f(fd_StoredGame_winner, value) { + return + } + } } // Has reports whether a field is populated. @@ -151,6 +159,8 @@ func (x *fastReflection_StoredGame) Has(fd protoreflect.FieldDescriptor) bool { return x.Black != "" case "checkers.checkers.StoredGame.red": return x.Red != "" + case "checkers.checkers.StoredGame.winner": + return x.Winner != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -177,6 +187,8 @@ func (x *fastReflection_StoredGame) Clear(fd protoreflect.FieldDescriptor) { x.Black = "" case "checkers.checkers.StoredGame.red": x.Red = "" + case "checkers.checkers.StoredGame.winner": + x.Winner = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -208,6 +220,9 @@ func (x *fastReflection_StoredGame) Get(descriptor protoreflect.FieldDescriptor) case "checkers.checkers.StoredGame.red": value := x.Red return protoreflect.ValueOfString(value) + case "checkers.checkers.StoredGame.winner": + value := x.Winner + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -238,6 +253,8 @@ func (x *fastReflection_StoredGame) Set(fd protoreflect.FieldDescriptor, value p x.Black = value.Interface().(string) case "checkers.checkers.StoredGame.red": x.Red = value.Interface().(string) + case "checkers.checkers.StoredGame.winner": + x.Winner = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -268,6 +285,8 @@ func (x *fastReflection_StoredGame) Mutable(fd protoreflect.FieldDescriptor) pro panic(fmt.Errorf("field black of message checkers.checkers.StoredGame is not mutable")) case "checkers.checkers.StoredGame.red": panic(fmt.Errorf("field red of message checkers.checkers.StoredGame is not mutable")) + case "checkers.checkers.StoredGame.winner": + panic(fmt.Errorf("field winner of message checkers.checkers.StoredGame is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -291,6 +310,8 @@ func (x *fastReflection_StoredGame) NewField(fd protoreflect.FieldDescriptor) pr return protoreflect.ValueOfString("") case "checkers.checkers.StoredGame.red": return protoreflect.ValueOfString("") + case "checkers.checkers.StoredGame.winner": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: checkers.checkers.StoredGame")) @@ -380,6 +401,10 @@ func (x *fastReflection_StoredGame) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.Winner) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -409,6 +434,13 @@ func (x *fastReflection_StoredGame) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.Winner) > 0 { + i -= len(x.Winner) + copy(dAtA[i:], x.Winner) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Winner))) + i-- + dAtA[i] = 0x32 + } if len(x.Red) > 0 { i -= len(x.Red) copy(dAtA[i:], x.Red) @@ -653,6 +685,38 @@ func (x *fastReflection_StoredGame) ProtoMethods() *protoiface.Methods { } x.Red = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Winner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Winner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -706,11 +770,12 @@ type StoredGame struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` - Board string `protobuf:"bytes,2,opt,name=board,proto3" json:"board,omitempty"` - Turn string `protobuf:"bytes,3,opt,name=turn,proto3" json:"turn,omitempty"` - Black string `protobuf:"bytes,4,opt,name=black,proto3" json:"black,omitempty"` - Red string `protobuf:"bytes,5,opt,name=red,proto3" json:"red,omitempty"` + Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` + Board string `protobuf:"bytes,2,opt,name=board,proto3" json:"board,omitempty"` + Turn string `protobuf:"bytes,3,opt,name=turn,proto3" json:"turn,omitempty"` + Black string `protobuf:"bytes,4,opt,name=black,proto3" json:"black,omitempty"` + Red string `protobuf:"bytes,5,opt,name=red,proto3" json:"red,omitempty"` + Winner string `protobuf:"bytes,6,opt,name=winner,proto3" json:"winner,omitempty"` } func (x *StoredGame) Reset() { @@ -768,33 +833,42 @@ func (x *StoredGame) GetRed() string { return "" } +func (x *StoredGame) GetWinner() string { + if x != nil { + return x.Winner + } + return "" +} + var File_checkers_checkers_stored_game_proto protoreflect.FileDescriptor var file_checkers_checkers_stored_game_proto_rawDesc = []byte{ 0x0a, 0x23, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2e, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x22, 0x74, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x64, 0x47, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, - 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x64, 0x42, 0xc2, - 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2e, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x42, 0x0f, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x64, - 0x47, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6c, 0x69, 0x6d, 0x64, 0x7a, 0x68, 0x6f, - 0x6e, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, - 0xa2, 0x02, 0x03, 0x43, 0x43, 0x58, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, - 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0xca, 0x02, 0x11, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x65, 0x72, 0x73, 0x5c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0xe2, 0x02, - 0x1d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x5c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, - 0x72, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x3a, 0x3a, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x64, 0x47, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, + 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x10, 0x0a, + 0x03, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x42, 0xc2, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, + 0x73, 0x42, 0x0f, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x47, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6f, 0x6c, 0x69, 0x6d, 0x64, 0x7a, 0x68, 0x6f, 0x6e, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x72, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, + 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0xa2, 0x02, 0x03, 0x43, 0x43, 0x58, 0xaa, + 0x02, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x72, 0x73, 0xca, 0x02, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x5c, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0xe2, 0x02, 0x1d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, + 0x72, 0x73, 0x5c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, + 0x72, 0x73, 0x3a, 0x3a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/docs/static/openapi.yml b/docs/static/openapi.yml index 40cfced..4189e09 100644 --- a/docs/static/openapi.yml +++ b/docs/static/openapi.yml @@ -1 +1 @@ -{"id":"github.com/olimdzhon/checkers","consumes":["application/json"],"produces":["application/json"],"swagger":"2.0","info":{"description":"Chain github.com/olimdzhon/checkers REST API","title":"HTTP API Console","contact":{"name":"github.com/olimdzhon/checkers"},"version":"version not set"},"paths":{"/checkers.checkers.Msg/CreateGame":{"post":{"tags":["Msg"],"operationId":"GithubComolimdzhoncheckersMsg_CreateGame","parameters":[{"name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgCreateGame"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgCreateGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/checkers.checkers.Msg/PlayMove":{"post":{"tags":["Msg"],"operationId":"GithubComolimdzhoncheckersMsg_PlayMove","parameters":[{"name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgPlayMove"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgPlayMoveResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/checkers.checkers.Msg/UpdateParams":{"post":{"tags":["Msg"],"summary":"UpdateParams defines a (governance) operation for updating the module\nparameters. The authority defaults to the x/gov module account.","operationId":"GithubComolimdzhoncheckersMsg_UpdateParams","parameters":[{"description":"MsgUpdateParams is the Msg/UpdateParams request type.","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgUpdateParams"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgUpdateParamsResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/params":{"get":{"tags":["Query"],"summary":"Parameters queries the parameters of the module.","operationId":"GithubComolimdzhoncheckersQuery_Params","responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryParamsResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/stored_game":{"get":{"tags":["Query"],"operationId":"GithubComolimdzhoncheckersQuery_StoredGameAll","parameters":[{"type":"string","format":"byte","description":"key is a value returned in PageResponse.next_key to begin\nquerying the next page most efficiently. Only one of offset or key\nshould be set.","name":"pagination.key","in":"query"},{"type":"string","format":"uint64","description":"offset is a numeric offset that can be used when key is unavailable.\nIt is less efficient than using key. Only one of offset or key should\nbe set.","name":"pagination.offset","in":"query"},{"type":"string","format":"uint64","description":"limit is the total number of results to be returned in the result page.\nIf left empty it will default to a value to be set by each app.","name":"pagination.limit","in":"query"},{"type":"boolean","description":"count_total is set to true to indicate that the result set should include\na count of the total number of items available for pagination in UIs.\ncount_total is only respected when offset is used. It is ignored when key\nis set.","name":"pagination.count_total","in":"query"},{"type":"boolean","description":"reverse is set to true if results are to be returned in the descending order.\n\nSince: cosmos-sdk 0.43","name":"pagination.reverse","in":"query"}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryAllStoredGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/stored_game/{index}":{"get":{"tags":["Query"],"summary":"Queries a list of StoredGame items.","operationId":"GithubComolimdzhoncheckersQuery_StoredGame","parameters":[{"type":"string","name":"index","in":"path","required":true}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryGetStoredGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/system_info":{"get":{"tags":["Query"],"summary":"Queries a SystemInfo by index.","operationId":"GithubComolimdzhoncheckersQuery_SystemInfo","responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryGetSystemInfoResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}}},"definitions":{"checkers.checkers.MsgCreateGame":{"type":"object","properties":{"black":{"type":"string"},"creator":{"type":"string"},"red":{"type":"string"}}},"checkers.checkers.MsgCreateGameResponse":{"type":"object","properties":{"gameIndex":{"type":"string"}}},"checkers.checkers.MsgPlayMove":{"type":"object","properties":{"creator":{"type":"string"},"fromX":{"type":"string","format":"uint64"},"fromY":{"type":"string","format":"uint64"},"gameIndex":{"type":"string"},"toX":{"type":"string","format":"uint64"},"toY":{"type":"string","format":"uint64"}}},"checkers.checkers.MsgPlayMoveResponse":{"type":"object","properties":{"capturedX":{"type":"integer","format":"int32"},"capturedY":{"type":"integer","format":"int32"},"winner":{"type":"string"}}},"checkers.checkers.MsgUpdateParams":{"description":"MsgUpdateParams is the Msg/UpdateParams request type.","type":"object","properties":{"authority":{"description":"authority is the address that controls the module (defaults to x/gov unless overwritten).","type":"string"},"params":{"description":"NOTE: All parameters must be supplied.","$ref":"#/definitions/checkers.checkers.Params"}}},"checkers.checkers.MsgUpdateParamsResponse":{"description":"MsgUpdateParamsResponse defines the response structure for executing a\nMsgUpdateParams message.","type":"object"},"checkers.checkers.Params":{"description":"Params defines the parameters for the module.","type":"object"},"checkers.checkers.QueryAllStoredGameResponse":{"type":"object","properties":{"pagination":{"$ref":"#/definitions/cosmos.base.query.v1beta1.PageResponse"},"storedGame":{"type":"array","items":{"type":"object","$ref":"#/definitions/checkers.checkers.StoredGame"}}}},"checkers.checkers.QueryGetStoredGameResponse":{"type":"object","properties":{"storedGame":{"$ref":"#/definitions/checkers.checkers.StoredGame"}}},"checkers.checkers.QueryGetSystemInfoResponse":{"type":"object","properties":{"SystemInfo":{"$ref":"#/definitions/checkers.checkers.SystemInfo"}}},"checkers.checkers.QueryParamsResponse":{"description":"QueryParamsResponse is response type for the Query/Params RPC method.","type":"object","properties":{"params":{"description":"params holds all the parameters of this module.","$ref":"#/definitions/checkers.checkers.Params"}}},"checkers.checkers.StoredGame":{"type":"object","properties":{"black":{"type":"string"},"board":{"type":"string"},"index":{"type":"string"},"red":{"type":"string"},"turn":{"type":"string"}}},"checkers.checkers.SystemInfo":{"type":"object","properties":{"nextId":{"type":"string","format":"uint64"}}},"cosmos.base.query.v1beta1.PageRequest":{"description":"message SomeRequest {\n Foo some_parameter = 1;\n PageRequest pagination = 2;\n }","type":"object","title":"PageRequest is to be embedded in gRPC request messages for efficient\npagination. Ex:","properties":{"count_total":{"description":"count_total is set to true to indicate that the result set should include\na count of the total number of items available for pagination in UIs.\ncount_total is only respected when offset is used. It is ignored when key\nis set.","type":"boolean"},"key":{"description":"key is a value returned in PageResponse.next_key to begin\nquerying the next page most efficiently. Only one of offset or key\nshould be set.","type":"string","format":"byte"},"limit":{"description":"limit is the total number of results to be returned in the result page.\nIf left empty it will default to a value to be set by each app.","type":"string","format":"uint64"},"offset":{"description":"offset is a numeric offset that can be used when key is unavailable.\nIt is less efficient than using key. Only one of offset or key should\nbe set.","type":"string","format":"uint64"},"reverse":{"description":"reverse is set to true if results are to be returned in the descending order.\n\nSince: cosmos-sdk 0.43","type":"boolean"}}},"cosmos.base.query.v1beta1.PageResponse":{"description":"PageResponse is to be embedded in gRPC response messages where the\ncorresponding request message has used PageRequest.\n\n message SomeResponse {\n repeated Bar results = 1;\n PageResponse page = 2;\n }","type":"object","properties":{"next_key":{"description":"next_key is the key to be passed to PageRequest.key to\nquery the next page most efficiently. It will be empty if\nthere are no more results.","type":"string","format":"byte"},"total":{"type":"string","format":"uint64","title":"total is total number of results available if PageRequest.count_total\nwas set, its value is undefined otherwise"}}},"google.protobuf.Any":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"google.rpc.Status":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"details":{"type":"array","items":{"type":"object","$ref":"#/definitions/google.protobuf.Any"}},"message":{"type":"string"}}}},"tags":[{"name":"Query"},{"name":"Msg"}]} \ No newline at end of file +{"id":"github.com/olimdzhon/checkers","consumes":["application/json"],"produces":["application/json"],"swagger":"2.0","info":{"description":"Chain github.com/olimdzhon/checkers REST API","title":"HTTP API Console","contact":{"name":"github.com/olimdzhon/checkers"},"version":"version not set"},"paths":{"/checkers.checkers.Msg/CreateGame":{"post":{"tags":["Msg"],"operationId":"GithubComolimdzhoncheckersMsg_CreateGame","parameters":[{"name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgCreateGame"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgCreateGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/checkers.checkers.Msg/PlayMove":{"post":{"tags":["Msg"],"operationId":"GithubComolimdzhoncheckersMsg_PlayMove","parameters":[{"name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgPlayMove"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgPlayMoveResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/checkers.checkers.Msg/UpdateParams":{"post":{"tags":["Msg"],"summary":"UpdateParams defines a (governance) operation for updating the module\nparameters. The authority defaults to the x/gov module account.","operationId":"GithubComolimdzhoncheckersMsg_UpdateParams","parameters":[{"description":"MsgUpdateParams is the Msg/UpdateParams request type.","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/checkers.checkers.MsgUpdateParams"}}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.MsgUpdateParamsResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/params":{"get":{"tags":["Query"],"summary":"Parameters queries the parameters of the module.","operationId":"GithubComolimdzhoncheckersQuery_Params","responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryParamsResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/stored_game":{"get":{"tags":["Query"],"operationId":"GithubComolimdzhoncheckersQuery_StoredGameAll","parameters":[{"type":"string","format":"byte","description":"key is a value returned in PageResponse.next_key to begin\nquerying the next page most efficiently. Only one of offset or key\nshould be set.","name":"pagination.key","in":"query"},{"type":"string","format":"uint64","description":"offset is a numeric offset that can be used when key is unavailable.\nIt is less efficient than using key. Only one of offset or key should\nbe set.","name":"pagination.offset","in":"query"},{"type":"string","format":"uint64","description":"limit is the total number of results to be returned in the result page.\nIf left empty it will default to a value to be set by each app.","name":"pagination.limit","in":"query"},{"type":"boolean","description":"count_total is set to true to indicate that the result set should include\na count of the total number of items available for pagination in UIs.\ncount_total is only respected when offset is used. It is ignored when key\nis set.","name":"pagination.count_total","in":"query"},{"type":"boolean","description":"reverse is set to true if results are to be returned in the descending order.\n\nSince: cosmos-sdk 0.43","name":"pagination.reverse","in":"query"}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryAllStoredGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/stored_game/{index}":{"get":{"tags":["Query"],"summary":"Queries a list of StoredGame items.","operationId":"GithubComolimdzhoncheckersQuery_StoredGame","parameters":[{"type":"string","name":"index","in":"path","required":true}],"responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryGetStoredGameResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}},"/olimdzhon/checkers/checkers/system_info":{"get":{"tags":["Query"],"summary":"Queries a SystemInfo by index.","operationId":"GithubComolimdzhoncheckersQuery_SystemInfo","responses":{"200":{"description":"A successful response.","schema":{"$ref":"#/definitions/checkers.checkers.QueryGetSystemInfoResponse"}},"default":{"description":"An unexpected error response.","schema":{"$ref":"#/definitions/google.rpc.Status"}}}}}},"definitions":{"checkers.checkers.MsgCreateGame":{"type":"object","properties":{"black":{"type":"string"},"creator":{"type":"string"},"red":{"type":"string"}}},"checkers.checkers.MsgCreateGameResponse":{"type":"object","properties":{"gameIndex":{"type":"string"}}},"checkers.checkers.MsgPlayMove":{"type":"object","properties":{"creator":{"type":"string"},"fromX":{"type":"string","format":"uint64"},"fromY":{"type":"string","format":"uint64"},"gameIndex":{"type":"string"},"toX":{"type":"string","format":"uint64"},"toY":{"type":"string","format":"uint64"}}},"checkers.checkers.MsgPlayMoveResponse":{"type":"object","properties":{"capturedX":{"type":"integer","format":"int32"},"capturedY":{"type":"integer","format":"int32"},"winner":{"type":"string"}}},"checkers.checkers.MsgUpdateParams":{"description":"MsgUpdateParams is the Msg/UpdateParams request type.","type":"object","properties":{"authority":{"description":"authority is the address that controls the module (defaults to x/gov unless overwritten).","type":"string"},"params":{"description":"NOTE: All parameters must be supplied.","$ref":"#/definitions/checkers.checkers.Params"}}},"checkers.checkers.MsgUpdateParamsResponse":{"description":"MsgUpdateParamsResponse defines the response structure for executing a\nMsgUpdateParams message.","type":"object"},"checkers.checkers.Params":{"description":"Params defines the parameters for the module.","type":"object"},"checkers.checkers.QueryAllStoredGameResponse":{"type":"object","properties":{"pagination":{"$ref":"#/definitions/cosmos.base.query.v1beta1.PageResponse"},"storedGame":{"type":"array","items":{"type":"object","$ref":"#/definitions/checkers.checkers.StoredGame"}}}},"checkers.checkers.QueryGetStoredGameResponse":{"type":"object","properties":{"storedGame":{"$ref":"#/definitions/checkers.checkers.StoredGame"}}},"checkers.checkers.QueryGetSystemInfoResponse":{"type":"object","properties":{"SystemInfo":{"$ref":"#/definitions/checkers.checkers.SystemInfo"}}},"checkers.checkers.QueryParamsResponse":{"description":"QueryParamsResponse is response type for the Query/Params RPC method.","type":"object","properties":{"params":{"description":"params holds all the parameters of this module.","$ref":"#/definitions/checkers.checkers.Params"}}},"checkers.checkers.StoredGame":{"type":"object","properties":{"black":{"type":"string"},"board":{"type":"string"},"index":{"type":"string"},"red":{"type":"string"},"turn":{"type":"string"},"winner":{"type":"string"}}},"checkers.checkers.SystemInfo":{"type":"object","properties":{"nextId":{"type":"string","format":"uint64"}}},"cosmos.base.query.v1beta1.PageRequest":{"description":"message SomeRequest {\n Foo some_parameter = 1;\n PageRequest pagination = 2;\n }","type":"object","title":"PageRequest is to be embedded in gRPC request messages for efficient\npagination. Ex:","properties":{"count_total":{"description":"count_total is set to true to indicate that the result set should include\na count of the total number of items available for pagination in UIs.\ncount_total is only respected when offset is used. It is ignored when key\nis set.","type":"boolean"},"key":{"description":"key is a value returned in PageResponse.next_key to begin\nquerying the next page most efficiently. Only one of offset or key\nshould be set.","type":"string","format":"byte"},"limit":{"description":"limit is the total number of results to be returned in the result page.\nIf left empty it will default to a value to be set by each app.","type":"string","format":"uint64"},"offset":{"description":"offset is a numeric offset that can be used when key is unavailable.\nIt is less efficient than using key. Only one of offset or key should\nbe set.","type":"string","format":"uint64"},"reverse":{"description":"reverse is set to true if results are to be returned in the descending order.\n\nSince: cosmos-sdk 0.43","type":"boolean"}}},"cosmos.base.query.v1beta1.PageResponse":{"description":"PageResponse is to be embedded in gRPC response messages where the\ncorresponding request message has used PageRequest.\n\n message SomeResponse {\n repeated Bar results = 1;\n PageResponse page = 2;\n }","type":"object","properties":{"next_key":{"description":"next_key is the key to be passed to PageRequest.key to\nquery the next page most efficiently. It will be empty if\nthere are no more results.","type":"string","format":"byte"},"total":{"type":"string","format":"uint64","title":"total is total number of results available if PageRequest.count_total\nwas set, its value is undefined otherwise"}}},"google.protobuf.Any":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"google.rpc.Status":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"details":{"type":"array","items":{"type":"object","$ref":"#/definitions/google.protobuf.Any"}},"message":{"type":"string"}}}},"tags":[{"name":"Query"},{"name":"Msg"}]} \ No newline at end of file diff --git a/proto/checkers/checkers/stored_game.proto b/proto/checkers/checkers/stored_game.proto index 5842ada..e31672d 100644 --- a/proto/checkers/checkers/stored_game.proto +++ b/proto/checkers/checkers/stored_game.proto @@ -9,6 +9,6 @@ message StoredGame { string turn = 3; string black = 4; string red = 5; - + string winner = 6; } diff --git a/x/checkers/keeper/msg_server_create_game.go b/x/checkers/keeper/msg_server_create_game.go index 98c41a4..9aa2a46 100644 --- a/x/checkers/keeper/msg_server_create_game.go +++ b/x/checkers/keeper/msg_server_create_game.go @@ -25,6 +25,7 @@ func (k msgServer) CreateGame(goCtx context.Context, msg *types.MsgCreateGame) ( Turn: rules.PieceStrings[newGame.Turn], Black: msg.Black, Red: msg.Red, + Winner: rules.PieceStrings[rules.NO_PLAYER], } err := storedGame.Validate() diff --git a/x/checkers/keeper/msg_server_play_move.go b/x/checkers/keeper/msg_server_play_move.go index 9a7bec2..d1305dd 100644 --- a/x/checkers/keeper/msg_server_play_move.go +++ b/x/checkers/keeper/msg_server_play_move.go @@ -18,6 +18,10 @@ func (k msgServer) PlayMove(goCtx context.Context, msg *types.MsgPlayMove) (*typ return nil, errorsmod.Wrapf(types.ErrGameNotFound, "%s", msg.GameIndex) } + if storedGame.Winner != rules.PieceStrings[rules.NO_PLAYER] { + return nil, types.ErrGameFinished + } + isBlack := storedGame.Black == msg.Creator isRed := storedGame.Red == msg.Creator var player rules.Player @@ -54,7 +58,15 @@ func (k msgServer) PlayMove(goCtx context.Context, msg *types.MsgPlayMove) (*typ return nil, errorsmod.Wrapf(types.ErrWrongMove, moveErr.Error()) } - storedGame.Board = game.String() + storedGame.Winner = rules.PieceStrings[game.Winner()] + + lastBoard := game.String() + if storedGame.Winner == rules.PieceStrings[rules.NO_PLAYER] { + storedGame.Board = lastBoard + } else { + storedGame.Board = "" + } + storedGame.Turn = rules.PieceStrings[game.Turn] k.Keeper.SetStoredGame(ctx, storedGame) @@ -65,6 +77,7 @@ func (k msgServer) PlayMove(goCtx context.Context, msg *types.MsgPlayMove) (*typ sdk.NewAttribute(types.MovePlayedEventCapturedX, strconv.FormatInt(int64(captured.X), 10)), sdk.NewAttribute(types.MovePlayedEventCapturedY, strconv.FormatInt(int64(captured.Y), 10)), sdk.NewAttribute(types.MovePlayedEventWinner, rules.PieceStrings[game.Winner()]), + sdk.NewAttribute(types.MovePlayedEventBoard, lastBoard), ), ) diff --git a/x/checkers/keeper/msg_server_play_move_test.go b/x/checkers/keeper/msg_server_play_move_test.go index 5bb2f6d..3c038fe 100644 --- a/x/checkers/keeper/msg_server_play_move_test.go +++ b/x/checkers/keeper/msg_server_play_move_test.go @@ -67,6 +67,7 @@ func TestPlayMoveSavedGame(t *testing.T) { Turn: "r", Black: bob, Red: carol, + Winner: "*", }, game1) } diff --git a/x/checkers/keeper/msg_server_play_move_winner_test.go b/x/checkers/keeper/msg_server_play_move_winner_test.go new file mode 100644 index 0000000..030d040 --- /dev/null +++ b/x/checkers/keeper/msg_server_play_move_winner_test.go @@ -0,0 +1,46 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/olimdzhon/checkers/x/checkers/testutil" + "github.com/olimdzhon/checkers/x/checkers/types" + "github.com/stretchr/testify/require" +) + +func TestPlayMoveUpToWinner(t *testing.T) { + msgServer, keeper, context := setupMsgServerWithOneGameForPlayMove(t) + ctx := sdk.UnwrapSDKContext(context) + + testutil.PlayAllMoves(t, msgServer, context, "1", bob, carol, testutil.Game1Moves) + + systemInfo, found := keeper.GetSystemInfo(ctx) + require.True(t, found) + require.EqualValues(t, types.SystemInfo{ + NextId: 2, + }, systemInfo) + + game, found := keeper.GetStoredGame(ctx, "1") + require.True(t, found) + require.EqualValues(t, types.StoredGame{ + Index: "1", + Board: "", + Turn: "b", + Black: bob, + Red: carol, + Winner: "b", + }, game) + events := sdk.StringifyEvents(ctx.EventManager().ABCIEvents()) + require.Len(t, events, 2) + event := events[0] + require.Equal(t, event.Type, "move-played") + require.EqualValues(t, []sdk.Attribute{ + {Key: "creator", Value: bob}, + {Key: "game-index", Value: "1"}, + {Key: "captured-x", Value: "2"}, + {Key: "captured-y", Value: "5"}, + {Key: "winner", Value: "b"}, + {Key: "board", Value: "*b*b****|**b*b***|*****b**|********|***B****|********|*****b**|********"}, + }, event.Attributes[(len(testutil.Game1Moves)-1)*6:]) +} \ No newline at end of file diff --git a/x/checkers/testutil/full_game_helpers.go b/x/checkers/testutil/full_game_helpers.go new file mode 100644 index 0000000..23b2d95 --- /dev/null +++ b/x/checkers/testutil/full_game_helpers.go @@ -0,0 +1,91 @@ +package testutil + +import ( + "context" + "testing" + + "github.com/olimdzhon/checkers/x/checkers/types" + "github.com/stretchr/testify/require" +) + +type GameMoveTest struct { + player string + fromX uint64 + fromY uint64 + toX uint64 + toY uint64 +} + +var ( + Game1Moves = []GameMoveTest{ + {"b", 1, 2, 2, 3}, // "*b*b*b*b|b*b*b*b*|***b*b*b|**b*****|********|r*r*r*r*|*r*r*r*r|r*r*r*r*" + {"r", 0, 5, 1, 4}, // "*b*b*b*b|b*b*b*b*|***b*b*b|**b*****|*r******|**r*r*r*|*r*r*r*r|r*r*r*r*" + {"b", 2, 3, 0, 5}, // "*b*b*b*b|b*b*b*b*|***b*b*b|********|********|b*r*r*r*|*r*r*r*r|r*r*r*r*" + {"r", 4, 5, 3, 4}, // "*b*b*b*b|b*b*b*b*|***b*b*b|********|***r****|b*r***r*|*r*r*r*r|r*r*r*r*" + {"b", 3, 2, 2, 3}, // "*b*b*b*b|b*b*b*b*|*****b*b|**b*****|***r****|b*r***r*|*r*r*r*r|r*r*r*r*" + {"r", 3, 4, 1, 2}, // "*b*b*b*b|b*b*b*b*|*r***b*b|********|********|b*r***r*|*r*r*r*r|r*r*r*r*" + {"b", 0, 1, 2, 3}, // "*b*b*b*b|**b*b*b*|*****b*b|**b*****|********|b*r***r*|*r*r*r*r|r*r*r*r*" + {"r", 2, 5, 3, 4}, // "*b*b*b*b|**b*b*b*|*****b*b|**b*****|***r****|b*****r*|*r*r*r*r|r*r*r*r*" + {"b", 2, 3, 4, 5}, // "*b*b*b*b|**b*b*b*|*****b*b|********|********|b***b*r*|*r*r*r*r|r*r*r*r*" + {"r", 5, 6, 3, 4}, // "*b*b*b*b|**b*b*b*|*****b*b|********|***r****|b*****r*|*r*r***r|r*r*r*r*" + {"b", 5, 2, 4, 3}, // "*b*b*b*b|**b*b*b*|*******b|****b***|***r****|b*****r*|*r*r***r|r*r*r*r*" + {"r", 3, 4, 5, 2}, // "*b*b*b*b|**b*b*b*|*****r*b|********|********|b*****r*|*r*r***r|r*r*r*r*" + {"b", 6, 1, 4, 3}, // "*b*b*b*b|**b*b***|*******b|****b***|********|b*****r*|*r*r***r|r*r*r*r*" + {"r", 6, 5, 5, 4}, // "*b*b*b*b|**b*b***|*******b|****b***|*****r**|b*******|*r*r***r|r*r*r*r*" + {"b", 4, 3, 6, 5}, // "*b*b*b*b|**b*b***|*******b|********|********|b*****b*|*r*r***r|r*r*r*r*" + {"r", 7, 6, 5, 4}, // "*b*b*b*b|**b*b***|*******b|********|*****r**|b*******|*r*r****|r*r*r*r*" + {"b", 7, 2, 6, 3}, // "*b*b*b*b|**b*b***|********|******b*|*****r**|b*******|*r*r****|r*r*r*r*" + {"r", 5, 4, 7, 2}, // "*b*b*b*b|**b*b***|*******r|********|********|b*******|*r*r****|r*r*r*r*" + {"b", 4, 1, 3, 2}, // "*b*b*b*b|**b*****|***b***r|********|********|b*******|*r*r****|r*r*r*r*" + {"r", 3, 6, 4, 5}, // "*b*b*b*b|**b*****|***b***r|********|********|b***r***|*r******|r*r*r*r*" + {"b", 5, 0, 4, 1}, // "*b*b***b|**b*b***|***b***r|********|********|b***r***|*r******|r*r*r*r*" + {"r", 2, 7, 3, 6}, // "*b*b***b|**b*b***|***b***r|********|********|b***r***|*r*r****|r***r*r*" + {"b", 0, 5, 2, 7}, // "*b*b***b|**b*b***|***b***r|********|********|****r***|***r****|r*B*r*r*" + {"r", 4, 5, 3, 4}, // "*b*b***b|**b*b***|***b***r|********|***r****|********|***r****|r*B*r*r*" + {"b", 2, 7, 4, 5}, // "*b*b***b|**b*b***|***b***r|********|***r****|****B***|********|r***r*r*" + // Captures again + {"b", 4, 5, 2, 3}, // "*b*b***b|**b*b***|***b***r|**B*****|********|********|********|r***r*r*" + {"r", 6, 7, 5, 6}, // "*b*b***b|**b*b***|***b***r|**B*****|********|********|*****r**|r***r***" + {"b", 2, 3, 3, 4}, // "*b*b***b|**b*b***|***b***r|********|***B****|********|*****r**|r***r***" + {"r", 0, 7, 1, 6}, // "*b*b***b|**b*b***|***b***r|********|***B****|********|*r***r**|****r***" + {"b", 3, 2, 4, 3}, // "*b*b***b|**b*b***|*******r|****b***|***B****|********|*r***r**|****r***" + {"r", 7, 2, 6, 1}, // "*b*b***b|**b*b*r*|********|****b***|***B****|********|*r***r**|****r***" + {"b", 7, 0, 5, 2}, // "*b*b****|**b*b***|*****b**|****b***|***B****|********|*r***r**|****r***" + {"r", 1, 6, 2, 5}, // "*b*b****|**b*b***|*****b**|****b***|***B****|**r*****|*****r**|****r***" + {"b", 3, 4, 1, 6}, // "*b*b****|**b*b***|*****b**|****b***|********|********|*B***r**|****r***" + {"r", 4, 7, 3, 6}, // "*b*b****|**b*b***|*****b**|****b***|********|********|*B*r*r**|********" + {"b", 4, 3, 3, 4}, // "*b*b****|**b*b***|*****b**|********|***b****|********|*B*r*r**|********" + {"r", 5, 6, 4, 5}, // "*b*b****|**b*b***|*****b**|********|***b****|****r***|*B*r****|********" + {"b", 3, 4, 5, 6}, // "*b*b****|**b*b***|*****b**|********|********|********|*B*r*b**|********" + {"r", 3, 6, 2, 5}, // "*b*b****|**b*b***|*****b**|********|********|**r*****|*B***b**|********" + {"b", 1, 6, 3, 4}, // "*b*b****|**b*b***|*****b**|********|***B****|********|*****b**|********" + } +) + +func GetPlayer(color string, black string, red string) string { + if color == "b" { + return black + } + return red +} + +func PlayAllMoves( + t *testing.T, + msgServer types.MsgServer, + context context.Context, + gameIndex string, + black string, + red string, + moves []GameMoveTest) { + for _, move := range moves { + _, err := msgServer.PlayMove(context, &types.MsgPlayMove{ + Creator: GetPlayer(move.player, black, red), + GameIndex: gameIndex, + FromX: move.fromX, + FromY: move.fromY, + ToX: move.toX, + ToY: move.toY, + }) + require.Nil(t, err) + } +} \ No newline at end of file diff --git a/x/checkers/types/errors.go b/x/checkers/types/errors.go index 0b32049..bd48dff 100644 --- a/x/checkers/types/errors.go +++ b/x/checkers/types/errors.go @@ -20,5 +20,5 @@ var ( ErrCreatorNotPlayer = sdkerrors.Register(ModuleName, 1109, "message creator is not a player") ErrNotPlayerTurn = sdkerrors.Register(ModuleName, 1110, "player tried to play out of turn") ErrWrongMove = sdkerrors.Register(ModuleName, 1111, "wrong move") - + ErrGameFinished = sdkerrors.Register(ModuleName, 1112, "game is already finished") ) diff --git a/x/checkers/types/full_game.go b/x/checkers/types/full_game.go index 6b3de27..b25ab12 100644 --- a/x/checkers/types/full_game.go +++ b/x/checkers/types/full_game.go @@ -31,6 +31,26 @@ func (storedGame StoredGame) ParseGame() (game *rules.Game, err error) { return board, nil } +func (storedGame StoredGame) GetPlayerAddress(color string) (address sdk.AccAddress, found bool, err error) { + black, err := storedGame.GetBlackAddress() + if err != nil { + return nil, false, err + } + red, err := storedGame.GetRedAddress() + if err != nil { + return nil, false, err + } + address, found = map[string]sdk.AccAddress{ + rules.PieceStrings[rules.BLACK_PLAYER]: black, + rules.PieceStrings[rules.RED_PLAYER]: red, + }[color] + return address, found, nil +} + +func (storedGame StoredGame) GetWinnerAddress() (address sdk.AccAddress, found bool, err error) { + return storedGame.GetPlayerAddress(storedGame.Winner) +} + func (storedGame StoredGame) Validate() (err error) { _, err = storedGame.GetBlackAddress() if err != nil { diff --git a/x/checkers/types/keys.go b/x/checkers/types/keys.go index 1ef396f..e8dc1bb 100644 --- a/x/checkers/types/keys.go +++ b/x/checkers/types/keys.go @@ -38,4 +38,5 @@ const ( MovePlayedEventCapturedX = "captured-x" MovePlayedEventCapturedY = "captured-y" MovePlayedEventWinner = "winner" + MovePlayedEventBoard = "board" ) \ No newline at end of file diff --git a/x/checkers/types/stored_game.pb.go b/x/checkers/types/stored_game.pb.go index 069d123..9a58e5e 100644 --- a/x/checkers/types/stored_game.pb.go +++ b/x/checkers/types/stored_game.pb.go @@ -23,11 +23,12 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type StoredGame struct { - Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` - Board string `protobuf:"bytes,2,opt,name=board,proto3" json:"board,omitempty"` - Turn string `protobuf:"bytes,3,opt,name=turn,proto3" json:"turn,omitempty"` - Black string `protobuf:"bytes,4,opt,name=black,proto3" json:"black,omitempty"` - Red string `protobuf:"bytes,5,opt,name=red,proto3" json:"red,omitempty"` + Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` + Board string `protobuf:"bytes,2,opt,name=board,proto3" json:"board,omitempty"` + Turn string `protobuf:"bytes,3,opt,name=turn,proto3" json:"turn,omitempty"` + Black string `protobuf:"bytes,4,opt,name=black,proto3" json:"black,omitempty"` + Red string `protobuf:"bytes,5,opt,name=red,proto3" json:"red,omitempty"` + Winner string `protobuf:"bytes,6,opt,name=winner,proto3" json:"winner,omitempty"` } func (m *StoredGame) Reset() { *m = StoredGame{} } @@ -98,6 +99,13 @@ func (m *StoredGame) GetRed() string { return "" } +func (m *StoredGame) GetWinner() string { + if m != nil { + return m.Winner + } + return "" +} + func init() { proto.RegisterType((*StoredGame)(nil), "checkers.checkers.StoredGame") } @@ -107,20 +115,21 @@ func init() { } var fileDescriptor_6a777ebb9b26769b = []byte{ - // 204 bytes of a gzipped FileDescriptorProto + // 221 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4e, 0xce, 0x48, 0x4d, 0xce, 0x4e, 0x2d, 0x2a, 0xd6, 0x87, 0x33, 0x8a, 0x4b, 0xf2, 0x8b, 0x52, 0x53, 0xe2, 0xd3, 0x13, 0x73, 0x53, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x04, 0x61, 0x72, 0x7a, 0x30, 0x86, 0x52, - 0x09, 0x17, 0x57, 0x30, 0x58, 0x9d, 0x7b, 0x62, 0x6e, 0xaa, 0x90, 0x08, 0x17, 0x6b, 0x66, 0x5e, - 0x4a, 0x6a, 0x85, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x84, 0x03, 0x12, 0x4d, 0xca, 0x4f, - 0x2c, 0x4a, 0x91, 0x60, 0x82, 0x88, 0x82, 0x39, 0x42, 0x42, 0x5c, 0x2c, 0x25, 0xa5, 0x45, 0x79, - 0x12, 0xcc, 0x60, 0x41, 0x30, 0x1b, 0xac, 0x32, 0x27, 0x31, 0x39, 0x5b, 0x82, 0x05, 0xaa, 0x12, - 0xc4, 0x11, 0x12, 0xe0, 0x62, 0x2e, 0x4a, 0x4d, 0x91, 0x60, 0x05, 0x8b, 0x81, 0x98, 0x4e, 0x1e, - 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, - 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x97, 0x9e, 0x59, 0x92, 0x51, - 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9f, 0x93, 0x99, 0x9b, 0x52, 0x95, 0x91, 0x9f, 0x87, - 0xf0, 0x53, 0x05, 0x82, 0x59, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0xf6, 0x99, 0x31, 0x20, - 0x00, 0x00, 0xff, 0xff, 0xbd, 0x98, 0xb5, 0x46, 0x00, 0x01, 0x00, 0x00, + 0x0f, 0x23, 0x17, 0x57, 0x30, 0x58, 0xa1, 0x7b, 0x62, 0x6e, 0xaa, 0x90, 0x08, 0x17, 0x6b, 0x66, + 0x5e, 0x4a, 0x6a, 0x85, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x84, 0x03, 0x12, 0x4d, 0xca, + 0x4f, 0x2c, 0x4a, 0x91, 0x60, 0x82, 0x88, 0x82, 0x39, 0x42, 0x42, 0x5c, 0x2c, 0x25, 0xa5, 0x45, + 0x79, 0x12, 0xcc, 0x60, 0x41, 0x30, 0x1b, 0xac, 0x32, 0x27, 0x31, 0x39, 0x5b, 0x82, 0x05, 0xaa, + 0x12, 0xc4, 0x11, 0x12, 0xe0, 0x62, 0x2e, 0x4a, 0x4d, 0x91, 0x60, 0x05, 0x8b, 0x81, 0x98, 0x42, + 0x62, 0x5c, 0x6c, 0xe5, 0x99, 0x79, 0x79, 0xa9, 0x45, 0x12, 0x6c, 0x60, 0x41, 0x28, 0xcf, 0xc9, + 0xe3, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, + 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xf4, 0xd2, 0x33, 0x4b, 0x32, + 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xf3, 0x73, 0x32, 0x73, 0x53, 0xaa, 0x32, 0xf2, 0xf3, + 0x10, 0x9e, 0xad, 0x40, 0x30, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x5e, 0x36, 0x06, + 0x04, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xbb, 0xa6, 0x5f, 0x19, 0x01, 0x00, 0x00, } func (m *StoredGame) Marshal() (dAtA []byte, err error) { @@ -143,6 +152,13 @@ func (m *StoredGame) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Winner) > 0 { + i -= len(m.Winner) + copy(dAtA[i:], m.Winner) + i = encodeVarintStoredGame(dAtA, i, uint64(len(m.Winner))) + i-- + dAtA[i] = 0x32 + } if len(m.Red) > 0 { i -= len(m.Red) copy(dAtA[i:], m.Red) @@ -218,6 +234,10 @@ func (m *StoredGame) Size() (n int) { if l > 0 { n += 1 + l + sovStoredGame(uint64(l)) } + l = len(m.Winner) + if l > 0 { + n += 1 + l + sovStoredGame(uint64(l)) + } return n } @@ -416,6 +436,38 @@ func (m *StoredGame) Unmarshal(dAtA []byte) error { } m.Red = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Winner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStoredGame + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStoredGame + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStoredGame + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Winner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStoredGame(dAtA[iNdEx:])