我正在做一个纸牌游戏,我有一个包含所有方法的父级组件。这些方法是我的“逻辑”,它确定如何根据“ house-way”设置随机生成的手。可以将house-way视为一组关于如何下注的规则。 我在如何构造组件方面遇到问题。我听说您应该将组件保持较小,并且我的组件已经长了300行。
有关如何进行重组的任何建议?我曾尝试将方法放在另一个文件中并导入它们,但是在设置状态时遇到了麻烦。换句话说,“ this.setState()”将引发错误,除非它是类的方法。
代码是一团糟,但是我基本上需要帮助使我的组件不那么肿胀。
export default class Layout extends Component {
constructor(props) {
console.log("starting up");
super(props);
//each hand holds a randomly generated tile object from { tilesSet }
this.state = {
//needs empty spots for when (mounting) <Hands hand1={this.state.hand[0].img} /> else error since hand[0] doesnt exist.
hand: ["", "", "", ""],
cards: false,
pairName: '',
rule: '',
show: false,
history: [],
test: 'test'
};
//binding in the constructor is recommended for performance.
this.handleToggle = this.handleToggle.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleHW = this.handleHW.bind(this);
this.assignHands = this.assignHands.bind(this);
this.checkPair = this.checkPair.bind(this);
this.checkTeenDey = this.checkTeenDey.bind(this);
this.hiLowMiddle = this.hiLowMiddle.bind(this);
this.compare = this.compare.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//n = pairTL, n2 = otherTL
split(n, n2){
//Gee Joon
if (n[0].pair === 1) {
let combo1 = baccaratCount(n2[0], n[0]);
let combo2 = baccaratCount(n2[1], n[1]);
//if it meets the split requirements...
if((combo1 >= 7 && combo2 >= 9) || (combo1 >= 9 && combo2 >= 7)){
console.log('got em', combo1, combo2);
return true;
}
else {
return true;
}
//Teen/Dey
// } else if(high[0].val === 2) {
// var combo1 = baccaratCount(high[0].val, low[0].val);
// var combo2 = baccaratCount(high[0].val, low[1].val);
// //checks if any of the tiles are 7,8, or 9. for 9 gong and wong.
// var check7_9 = low[0].val >= 7 && low[0].val <= 9;
// var check7_9_2 = low[1].val >= 7 && low[1].val <= 9;
// //regular 6-8 split rule.
// if((combo1 >= 6 && combo2 >= 8) || (combo1 >= 8 && combo2 >= 6)){
// moveTiles("split");
// return true;
// //we might have 7,8,9 with T/D. (with 8 and 9, it turns to 0 and 1, so we need this part.)
// } else if (check7_9 === true || check7_9_2 === true){
// //if both are 7,8, or 9
// if (check7_9 === check7_9_2){
// moveTiles("split");
// return true;
// //only if 1..
// } else if (check7_9 === true && check7_9_2 === false){
// if (low[1].val >= 3 && low[1].val <=6){
// moveTiles("split");
// return true;
// } else {
// moveTiles();
// return true;
// }
// //if other one...
// } else{
// if (low[0].val >= 3 && low[0].val <=6){
// moveTiles("split");
// return true;
// } else {
// moveTiles();
// return true;
// }
// }
// //does not split.
// } else {
// moveTiles();
// return;
// }
// } else {
// // all other pairs. split pairs are in one array with a length of 2. ex: [7, 9]
// var combo1 = baccaratCount(high[0].val, low[0].val);
// var combo2 = baccaratCount(high[0].val, low[1].val);
// if(combo1 >= high[0].split[0] && combo2 >= high[0].split[0]){
// moveTiles("split");
// } else {
// moveTiles();
// }
// return true;
// }
}
}
//checks for pairs. takes an array as arg
checkPair(hand){
for(let i = 0; i < hand.length; i++) {
for (let ii = 0; ii < hand.length; ii++) {
// if there is a pair and it is not comparing to itself.
if (hand[i].pair === hand[ii].pair && i !== ii) {
let pairTL = hand.filter((x) => x.rank === hand[i].rank); //array of the pair tiles
let otherTL = hand.filter((x) => x.rank !== hand[i].rank); // array of the other 2 tiles. use these two to move tiles accordingly
//if we split this pair...
if (hand[i].split !== false) {
//returns true if it split..
if(this.split(pairTL, otherTL)) {
let copyArr = [pairTL[0], otherTL[0], pairTL[1], otherTL[1]];
this.setState(() => ({hand: copyArr}));
}
else {
let copyArr = otherTL.concat(pairTL);
this.setState(() => ({hand: copyArr}));
return true;
}
}
//don't split
else {
let copyArr = otherTL.concat(pairTL); //concats the two small arrays together and renders.
this.setState(() => ({hand: copyArr, pairName: pairTL[0].name, rule: 'Don\'t Split'}))
return true;
}
}
}
}
return false; // no pairs
}
//will not execute if there is a pair...(checkPair returns true)
checkTeenDey(hand){
//true if we have teen or dey
let teenDey = hand.find((el) => el.val === 2) !== undefined;
//if true...
if(teenDey){
let tile = hand.find((el) => el.val === 2); // teen/ dey object
let tempArr = hand.filter((el) => el.name !== tile.name); //new arr without marked teen/dey. arr.length = 3
let secondTeenDey = tempArr.find((el) => el.val === 2); //second teen/dey (not pair)
let seven = tempArr.find((el) => el.val === 7);
let eight = tempArr.find((el) => el.val === 8);
let nine = tempArr.find((el) => el.val === 9);
//if there is a second teen/dey
if (secondTeenDey){
let twoArr = tempArr.filter((el) => el.name !== secondTeenDey.name);
console.log(tile, secondTeenDey, twoArr);
return true;
}
//look for 7,8,9
else if (seven){
console.log (seven);
return true;
}
else if(eight){
return true;
}
else if(nine){
return true;
}
}
// no teen or dey...
else{
return false;
}
}
//point system used for sort()
compare(a,b){
let comparison = 0;//no change
if(a.realValue < b.realValue){
comparison = -1;//a comes before b
}
else if(a.realValue > b.realValue){
comparison = 1;//b comes before a
}
return comparison;
}
//will not execute if there is a teen dey...
hiLowMiddle(hand){
//makes a new copy of hand and sorts it using sort()'s point system.
let sortedArr = hand.slice().sort(this.compare); //slice used, else mutates hand.
let tempHair = [sortedArr[0], sortedArr[3]];
let tempBack = [sortedArr[1], sortedArr[2]];
let hiLow = tempHair.concat(tempBack); //newly sorted arr
this.setState(() => ({hand: hiLow, rule: 'Hi-Low-Middle'}));
}
//generates new hand and updates them to state.
assignHands() {
let tempArr = [0, 0, 0, 0]; //filler array
let testArr = tilesSet.slice(); //filler array. tilesSet is untouched
//loops through and assigns random tile from deck
let newArr = tempArr.map((x) => {
let counter = Math.floor(Math.random()* (testArr.length - 1));
//used to hold the selected obj. needed since splice changes arr.length and we splice/display the different indexes.
let dummyArr = testArr[counter];
testArr.splice(counter, 1);
return dummyArr;
})
//updates state
this.setState({hand: [newArr[0], newArr[1], newArr[2], newArr[3]], show: true, history: [...this.state.history, [...newArr]]})
}
handleSubmit = (e) => {
e.preventDefault();
}
//toggle effect.
handleToggle = () => {
this.setState(() => ({cards: !this.state.cards}));
}
handleClick = () => {
assignHands(tilesSet);
//works, but not 100% properly. the changes are one step behind. fix async.
//check to see the history length. max set @ 20
if(this.state.history.length >= 10){
let temp = this.state.history.slice();
temp.shift();
this.setState(() => ({history: temp}))
}
}
//House Way
handleHW(){
if(!this.checkPair(this.state.hand)){
if(!this.checkTeenDey(this.state.hand)){
this.hiLowMiddle(this.state.hand);
}
}
}
render() {
return (
<div>
{this.state.show ? <h1>{baccaratCount(this.state.hand[0], this.state.hand[1]) + '/' + baccaratCount(this.state.hand[2], this.state.hand[3])}</h1> : <h1>Press New Hand to Start</h1>}
<form onSubmit={this.handleSubmit}>
<label>
<input type='text'/>
</label>
<button>submit</button>
</form>
<Input test={this.state.test}/>
<Hands
cards={this.state.cards}
hand1={this.state.hand[0].img}
hand2={this.state.hand[1].img}
hand3={this.state.hand[2].img}
hand4={this.state.hand[3].img}
/>
<Buttons
type="button"
className="btn btn-dark"
handleClick={this.handleClick}
handleHW={this.handleHW}
hand={this.state.hand}
/>
<h2>Value of tiles: {this.state.hand[0].val ? this.state.hand[0].val : "0"} - {this.state.hand[1].val ? this.state.hand[1].val : "0"} - {this.state.hand[2].val ? this.state.hand[2].val : "0"} - {this.state.hand[3].val ? this.state.hand[3].val : "0"}</h2>
<h2>Pair Name: {this.state.pairName}</h2>
<h2>Rule: {this.state.rule}</h2>
<h2>
History: <div>{this.state.history.map((el) => <li key={Math.random()}>{el.map((ele) => ele.name+ '--')}</li>)}</div>
</h2>
</div>
);
}
}