科百科
当前位置: 首页 范文大全

五子棋简单编程(详细教程附源码)

时间:2023-05-28 作者: 小编 阅读量: 5 栏目名: 范文大全

文章较长,建议收藏后学习!!解决方案:导入工具库tools.h,tools.cpp修改代码#include"tools.h"intmain{init();while{MOUSEMSGmsg=GetMouseMsg();if{//putimage;drawPNG;}}system;return0;}效果:修改:drawPNG;drawPNG;看上去,很完美,但是有一个严重的BUG!!当不在交叉点准确点击时,就会出现以上情况。如果小于阈值,就认为选择了哪个点。

文章较长,建议收藏后学习!!

1.项目分析2.项目目标
  • AI的基础应用
  • 算法的设计和实现
  • C语言的图形界面程序开发
3.项目准备
  • VS/VC(任意版本)
  • easyx图形库(直接双击即可安装)
  • 领取素材(传送门)(图片、音效)
4.创建项目
  1. 创建空项目。
  2. 把素材拷贝到项目目录下
5.画棋盘

画棋盘,播放开局提示、播放背景音乐

#include <graphics.h>//easyx图像库的头文件#include <windows.h>#include <mmsystem.h>//播放音乐的头文件#pragma comment(lib, "winmm.lib")void init() {initgraph(897, 895);loadimage(0, "res/棋盘.jpg");mciSendString("play res/start.wav", 0, 0, 0);mciSendString("play res/bg.mp3 repeat", 0, 0, 0);}int main(void) {init();system("pause");return 0;}

6.画棋子

鼠标点击后,在点击位置画棋子

IMAGE chessBlackImg;IMAGE chessWhiteImg;const float BLOCK_SIZE = 67.4; // 格子的大小void init() {......loadimage(&chessBlackImg, "res/black.png", BLOCK_SIZE, BLOCK_SIZE, true);loadimage(&chessWhiteImg, "res/white.png", BLOCK_SIZE, BLOCK_SIZE, true);}int main(void) {init();while (1) {MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN) {putimage(msg.x, msg.y, &chessBlackImg);}}system("pause");return 0;}

效果:

黑色区域,透明背景的PNG图片显示不了。

解决方案:

  1. 导入工具库tools.h, tools.cpp
  2. 修改代码

#include "tools.h"int main(void) {init();while (1) {MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN) {//putimage(msg.x, msg.y, &chessBlackImg);drawPNG(&chessBlackImg, msg.x, msg.y);}}system("pause");return 0;}

效果:

修改:

drawPNG(&chessBlackImg, msg.x, msg.y);drawPNG(&chessBlackImg, msg.x - 0.5 * BLOCK_SIZE, msg.y - 0.5 * BLOCK_SIZE);

看上去,很完美,但是有一个严重的BUG!!

当不在交叉点准确点击时,就会出现以上情况。

解决方案:

需要判断这个点击是否是合法未知的点击,并允许一定的偏差

判断有效的点击定义数据模型

因为点击时,要判断是否在已经有棋子的位置上点击(不能在已经落子的位置点击)

所以需要定义一个数据模型,来表示当前的所有棋子数据。

【模块化开发思想】

创建ChessData.h, 并把main.cpp中的与围棋相关的全局数据,剪贴到ChessData.h中

ChessData.h

#pragma onceconst float BLOCK_SIZE = 67.4; // 格子的大小const int BOARD_GRAD_SIZE = 13; //13x13棋盘大小const int POS_OFFSET = BLOCK_SIZE * 0.4; // 20 鼠标点击的模糊距离上限structChessData {// 存储当前游戏棋盘和棋子的情况,空白为0,黑子1,白子-1int chessMap[BOARD_GRAD_SIZE][BOARD_GRAD_SIZE];// 存储各个点位的评分情况,作为AI下棋依据int scoreMap[BOARD_GRAD_SIZE][BOARD_GRAD_SIZE];// 标示下棋方, true:黑棋方false: AI 白棋方(AI方)bool playerFlag;};

在main.cpp中添加围棋数据变量game

#include "ChessData.h"ChessData game;

初始化数据模型

ChessData.h

void initChessData(ChessData*); // 开始游戏

ChessData.cpp

void initChessData(ChessData *data){if (!data)return;memset(data->chessMap, 0, sizeof(data->chessMap));memset(data->scoreMap, 0, sizeof(data->scoreMap));data->playerFlag = true;}

main.cpp

void init() {......// 初始化游戏模型initChessData(&game);}

7.判断有效点击

判断原理

先计算出绿点,然后分别计算出3个黑点位置,计算当前位置离4个点的位置。

如果小于阈值(POS_OFFSET),就认为选择了哪个点。

在main.cpp中添加变量,存储有效点击的位置

int clickPosRow, clickPosCol; // 存储点击的位置

判断是否是有效点击,如果是有效点击,返回true并把结果保存到全局变量clickPosRow、 clickPosCol;

ChessData.h

const int POS_OFFSET = BLOCK_SIZE * 0.4; // 20 鼠标点击的模糊距离上限bool clickBoard(MOUSEMSG msg) {int x = msg.x;int y = msg.y;int col = (x - margin_x) / BLOCK_SIZE;int row = (y - margin_y) / BLOCK_SIZE;int leftTopPosX = margin_xBLOCK_SIZE * col;int leftTopPosY = margin_yBLOCK_SIZE * row;int len;int selectPos = false;do {len = sqrt((x - leftTopPosX) * (x - leftTopPosX)(y - leftTopPosY) * (y - leftTopPosY));if (len < POS_OFFSET) {clickPosRow = row;clickPosCol = col;if (game.chessMap[clickPosRow][clickPosCol] == 0) {selectPos = true;}break;}// 距离右上角的距离len = sqrt((x - leftTopPosX - BLOCK_SIZE) * (x - leftTopPosX - BLOCK_SIZE)(y - leftTopPosY) * (y - leftTopPosY));if (len < POS_OFFSET) {clickPosRow = row;clickPosCol = col1;if (game.chessMap[clickPosRow][clickPosCol] == 0) {selectPos = true;}break;}// 距离左下角的距离len = sqrt((x - leftTopPosX) * (x - leftTopPosX)(y - leftTopPosY - BLOCK_SIZE) * (y - leftTopPosY - BLOCK_SIZE));if (len < POS_OFFSET) {clickPosRow = row1;clickPosCol = col;if (game.chessMap[clickPosRow][clickPosCol] == 0) {selectPos = true;}break;}// 距离右下角的距离len = sqrt((x - leftTopPosX - BLOCK_SIZE) * (x - leftTopPosX - BLOCK_SIZE)(y - leftTopPosY - BLOCK_SIZE) * (y - leftTopPosY - BLOCK_SIZE));if (len < POS_OFFSET) {clickPosRow = row1;clickPosCol = col1;if (game.chessMap[clickPosRow][clickPosCol] == 0) {selectPos = true;}break;}} while (0);return selectPos;}

实现有效点击

int main(void) {init();while (1) {MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN && clickBoard(msg)) {//putimage(msg.x, msg.y, &chessBlackImg);//drawPNG(&chessBlackImg, msg.x - 0.5 * BLOCK_SIZE, msg.y - 0.5 * BLOCK_SIZE);int x = margin_xclickPosCol * BLOCK_SIZE - 0.5 * BLOCK_SIZE;int y = margin_yclickPosRow * BLOCK_SIZE - 0.5 * BLOCK_SIZE;drawPNG(&chessBlackImg, x, y);}}system("pause");return 0;}

测试效果:

8.优化项目架构1.封装画棋子的代码
  1. 在ChessData.h中添加棋子类型

typedef enum {CHESS_WHITE = -1,CHESS_BLACK = 1} chess_kind_t;

  1. 在main.cpp封装“落子”代码

void chessDown(int row, int col, chess_kind_t kind) {mciSendString("play res/down7.WAV", 0, 0, 0);int x = margin_xcol * BLOCK_SIZE - 0.5 * BLOCK_SIZE;int y = margin_yrow * BLOCK_SIZE - 0.5 * BLOCK_SIZE;if (kind == CHESS_WHITE) {drawPNG(&chessWhiteImg, x, y);}else {drawPNG(&chessBlackImg, x, y);}}

  1. 落子

int main(void) {init();while (1) {MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN && clickBoard(msg)) {chessDown(clickPosRow, clickPosCol, CHESS_BLACK);}}system("pause");return 0;}

2.优化项目架构

bool checkOver() { // 检查游戏是否结束return false;}void AI_GO() {//AI走棋}void manGo() { // 玩家走棋chessDown(clickPosRow, clickPosCol, CHESS_BLACK);}int main(void) {init();while (1) {MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN) {manGo();if (checkOver()) {init();continue;}AI_GO();if (checkOver()) {init();continue;}}}closegraph();return 0;}

9.更新游戏数据

人(黑方)落子后,还没有修改底层的游戏数据。

在ChessDatat.h添加接口:

void updateGameMap(ChessData* data, int row, int col);

在ChessData.cpp中添加实现。

void updateGameMap(ChessData* data, int row, int col){if (!data)return;if (data->playerFlag)data->chessMap[row][col] = 1;elsedata->chessMap[row][col] = -1;data->playerFlag = !data->playerFlag; // 换手}

应用更新:

void manGo() { // 玩家走棋chessDown(clickPosRow, clickPosCol, CHESS_BLACK);updateGameMap(&game, clickPosRow, clickPosCol);}

10.实现AI走棋五子棋入门

连2

活3

死3

活4

死4

连5(赢)

AI走棋原理

计算每个合法的落子点的“权值”,然后再权值最大的点落子

以后,可以在这个基础之上,实现多个层次的计算.

对于每个空白点,分别计算周围的八个方向

因为在计算某个方向时,正向和反向需同时考虑,所以实际上只需计算4个方向即可:

如果黑棋走这个点

产生效果

评分

连2

10

死3

30

活3

40

死4

60

活4

200

连5

20000

如果白棋AI走这个点

产生效果

评分

连1(普通)

5

连2

10

死3

25

活3

50

死4

55

活4

300

连5

30000

计算各点的“权值”

权值的计算,放在ChessData模块中。

ChessData.h

void calculateScore(ChessData* data);

ChessData.cpp

#include <string.h> //memset函数// 最关键的计算评分函数void calculateScore(ChessData* data){if (!data) return;// 统计玩家或者电脑连成的子int personNum = 0; // 玩家连成子的个数int botNum = 0; // AI连成子的个数int emptyNum = 0; // 各方向空白位的个数// 清空评分数组memset(data->scoreMap, 0, sizeof(data->scoreMap));for (int row = 0; row < BOARD_GRAD_SIZE; row)for (int col = 0; col < BOARD_GRAD_SIZE; col) {// 空白点就算if (row >= 0 && col >= 0 && data->chessMap[row][col] == 0){// 遍历周围4个方向,分别计算正反两个方向int directs[4][2] = { {1,0}, {1,1}, {0,1}, {-1,1 } };for (int k = 0; k < 4; k) {int x = directs[k][0];int y = directs[k][1];// 重置personNum = 0;botNum = 0;emptyNum = 0;// 对黑棋评分(正向)for (int i = 1; i <= 4; i) {if (rowi * y >= 0 && rowi * y < BOARD_GRAD_SIZE &&coli * x >= 0 && coli * x < BOARD_GRAD_SIZE &&data->chessMap[rowi * y][coli * x] == 1) { // 真人玩家的子personNum;} else if (rowi * y >= 0 && rowi * y < BOARD_GRAD_SIZE &&coli * x >= 0 && coli * x < BOARD_GRAD_SIZE &&data->chessMap[rowi * y][coli * x] == 0) { // 空白位emptyNum;break;// 遇到空白位置,停止该方向的搜索} else// 出边界,或者遇到白棋,就停止该方向的搜索break;}// 对黑棋评分(反向)for (int i = 1; i <= 4; i) {if (row - i * y >= 0 && row - i * y < BOARD_GRAD_SIZE &&col - i * x >= 0 && col - i * x < BOARD_GRAD_SIZE &&data->chessMap[row - i * y][col - i * x] == 1) { // 玩家的子personNum;}else if (row - i * y >= 0 && row - i * y < BOARD_GRAD_SIZE &&col - i * x >= 0 && col - i * x < BOARD_GRAD_SIZE &&data->chessMap[row - i * y][col - i * x] == 0) { // 空白位emptyNum;break;}else// 出边界,或者有AI自己的棋子break;}if (personNum == 1)// 杀二data->scoreMap[row][col]= 10;else if (personNum == 2) {// 杀三if (emptyNum == 1)// 死三data->scoreMap[row][col]= 30;else if (emptyNum == 2) // 活三data->scoreMap[row][col]= 40;} else if (personNum == 3) {// 杀四if (emptyNum == 1)//死四data->scoreMap[row][col]= 60;else if (emptyNum == 2) //活四data->scoreMap[row][col]= 200;}else if (personNum == 4)// 杀五data->scoreMap[row][col]= 20000;// 进行一次清空emptyNum = 0;// 对白棋评分(正向)for (int i = 1; i <= 4; i) {if (rowi * y > 0 && rowi * y < BOARD_GRAD_SIZE &&coli * x > 0 && coli * x < BOARD_GRAD_SIZE &&data->chessMap[rowi * y][coli * x] == -1) { // 玩家的子botNum;} else if (rowi * y > 0 && rowi * y < BOARD_GRAD_SIZE &&coli * x > 0 && coli * x < BOARD_GRAD_SIZE &&data->chessMap[rowi * y][coli * x] == 0){ // 空白位emptyNum;break;} elsebreak;}// 对白棋评分(反向)for (int i = 1; i <= 4; i) {if (row - i * y > 0 && row - i * y < BOARD_GRAD_SIZE &&col - i * x > 0 && col - i * x < BOARD_GRAD_SIZE &&data->chessMap[row - i * y][col - i * x] == -1) { // AI的子botNum;} else if (row - i * y > 0 && row - i * y < BOARD_GRAD_SIZE &&col - i * x > 0 && col - i * x < BOARD_GRAD_SIZE &&data->chessMap[row - i * y][col - i * x] == 0) { // 空白位emptyNum;break;} else// 出边界break;}if (botNum == 0)// 普通下子data->scoreMap[row][col]= 5;else if (botNum == 1)// 活二data->scoreMap[row][col]= 10;else if (botNum == 2) {if (emptyNum == 1)// 死三data->scoreMap[row][col]= 25;else if (emptyNum == 2)data->scoreMap[row][col]= 50;// 活三} else if (botNum == 3) {if (emptyNum == 1)// 死四data->scoreMap[row][col]= 55;else if (emptyNum == 2)data->scoreMap[row][col]= 300; // 活四} else if (botNum >= 4)data->scoreMap[row][col]= 30000;// 活五,应该具有最高优先级}}}}

AI思考落子点

在各落子点,找到分值最大的点。如果有多个分值相同的点,直接在其中取一个随机点。

在ChesssData模块实现。

ChessData.h

typedef struct point {int row;int col;} point_t;point_t actionByAI(ChessData* data); // 机器执行下棋

ChessData.cpp

#include <time.h>#include <stdlib.h>point_t actionByAI(ChessData *data){// 计算评分calculateScore(data);// 从评分中找出最大分数的位置int maxScore = 0;//std::vector<std::pair<int, int>> maxPoints;point_t maxPoints[BOARD_GRAD_SIZE * BOARD_GRAD_SIZE] = { 0, };int k=0;for (int row = 0; row < BOARD_GRAD_SIZE; row)for (int col = 0; col < BOARD_GRAD_SIZE; col){// 前提是这个坐标是空的if (data->chessMap[row][col] == 0){if (data->scoreMap[row][col] > maxScore)// 找最大的数和坐标{//maxPoints.clear();memset(maxPoints, 0, sizeof(maxPoints));k = 0;maxScore = data->scoreMap[row][col];//maxPoints.push_back(std::make_pair(row, col));maxPoints[k].row = row;maxPoints[k].col = col;k;}else if (data->scoreMap[row][col] == maxScore) {// 如果有多个最大的数,都存起来//maxPoints.push_back(std::make_pair(row, col));maxPoints[k].row = row;maxPoints[k].col = col;k;}}}// 随机落子,如果有多个点的话srand((unsigned)time(0));int index = rand() % k;return maxPoints[index];}

实现AI落子

void AI_GO() {//AI走棋point_t point = actionByAI(&game);clickPosRow = point.row;clickPosCol = point.col;Sleep(1000); //AI计算的太快,此处以假装思考chessDown(clickPosRow, clickPosCol, CHESS_WHITE);updateGameMap(&game, clickPosRow, clickPosCol);}

11.判断棋局是否结束在ChessData模块定义判断输赢的接口

原理分析:

在4个方向上搜索。

以右下方向为例:(黑色棋子表示刚下的棋子)

从当前棋子开始,向右下方数5个

从当前棋子的左上角开始,向右下方数5个

从当前棋子的左上第2个开始,向右下方数5个

从当前棋子的左上第3个开始,向右下方数5个

从当前棋子的左上第4个开始,向右下方数5个

ChessData.h

bool checkWin(ChessData* game, int row, int col); //row,col表示当前落子

ChessData.cpp

bool checkWin(ChessData* game, int row, int col){// 横竖斜四种大情况,每种情况都根据当前落子往后遍历5个棋子,有一种符合就算赢// 水平方向for (int i = 0; i < 5; i){// 往左5个,往右匹配4个子,20种情况if (col - i >= 0 &&col - i4 < BOARD_GRAD_SIZE &&game->chessMap[row][col - i] == game->chessMap[row][col - i1] &&game->chessMap[row][col - i] == game->chessMap[row][col - i2] &&game->chessMap[row][col - i] == game->chessMap[row][col - i3] &&game->chessMap[row][col - i] == game->chessMap[row][col - i4])return true;}// 竖直方向(上下延伸4个)for (int i = 0; i < 5; i){if (row - i >= 0 &&row - i4 < BOARD_GRAD_SIZE &&game->chessMap[row - i][col] == game->chessMap[row - i1][col] &&game->chessMap[row - i][col] == game->chessMap[row - i2][col] &&game->chessMap[row - i][col] == game->chessMap[row - i3][col] &&game->chessMap[row - i][col] == game->chessMap[row - i4][col])return true;}// “/"方向for (int i = 0; i < 5; i){if (rowi < BOARD_GRAD_SIZE &&rowi - 4 >= 0 &&col - i >= 0 &&col - i4 < BOARD_GRAD_SIZE &&// 第[row i]行,第[col-i]的棋子,与右上方连续4个棋子都相同game->chessMap[rowi][col - i] == game->chessMap[rowi - 1][col - i1] &&game->chessMap[rowi][col - i] == game->chessMap[rowi - 2][col - i2] &&game->chessMap[rowi][col - i] == game->chessMap[rowi - 3][col - i3] &&game->chessMap[rowi][col - i] == game->chessMap[rowi - 4][col - i4])return true;}// “\“ 方向for (int i = 0; i < 5; i){// 第[row i]行,第[col-i]的棋子,与右下方连续4个棋子都相同if (row - i >= 0 &&row - i4 < BOARD_GRAD_SIZE &&col - i >= 0 &&col - i4 < BOARD_GRAD_SIZE &&game->chessMap[row - i][col - i] == game->chessMap[row - i1][col - i1] &&game->chessMap[row - i][col - i] == game->chessMap[row - i2][col - i2] &&game->chessMap[row - i][col - i] == game->chessMap[row - i3][col - i3] &&game->chessMap[row - i][col - i] == game->chessMap[row - i4][col - i4])return true;}return false;}

调用AI接口

main.cpp

#include <stdio.h>bool checkOver() {if (checkWin(&game, clickPosRow, clickPosCol)) {Sleep(1500);if (game.playerFlag == false) {//黑棋赢(玩家赢),此时标记已经反转,轮到白棋落子mciSendString("play res/不错.mp3", 0, 0, 0);loadimage(0, "res/胜利.jpg");} else {mciSendString("play res/失败.mp3", 0, 0, 0);loadimage(0, "res/失败.jpg");}getch();return true;}return false;}

显示分数

在胜利窗口,或者失败窗口中,显示分数。

main.cpp

#define INIT_SCORE1000intscore;// 当前分数void initScore() {// 显示分数的字体设置settextcolor(WHITE);settextstyle(50, 0, "微软雅黑");FILE *fp = fopen("score.data", "rb");if (fp == NULL) {score = INIT_SCORE;} else {fread(&score, sizeof(score), 1, fp);}if (fp)fclose(fp);}void init() {......initScore();}

更新分数

ChessData.cpp

bool checkOver() {if (checkWin(&game, clickPosRow, clickPosCol)) {Sleep(1500);if (game.playerFlag == false) {//黑棋赢(玩家赢),此时标记已经反转,轮到白棋落子mciSendString("play res/不错.mp3", 0, 0, 0);loadimage(0, "res/胜利.jpg");score= 100;}else {mciSendString("play res/失败.mp3", 0, 0, 0);loadimage(0, "res/失败.jpg");score -= 100;}// 显示分数char scoreText[64];sprintf(scoreText, "当前分数 :%d", score);outtextxy(310, 800, scoreText);// 记录分数FILE* fp = fopen("score.data", "wb");fwrite(&score, sizeof(score), 1, fp);fclose(fp);getch();return true;}return false;}

项目迭代联网对战功能

通过项目的实战积累,在实战中成长

服务器联网通信开发。

游戏大厅配对功能

服务器端业务开发。

AI迭代

使用搜索树,提高算度。

    推荐阅读
  • 蛋黄果的核能吃吗(可以吃蛋黄果的核吗)

    跟着小编一起来看一看吧!蛋黄果的核能吃吗不可以。因为鸡蛋果的核含有毒素,容易对身体造成伤害,必须扔掉果核。鸡蛋果是一种热带水果,在室温下存放一周左右,用手轻轻捏住,感觉整个水果变得柔软可食用。鸡蛋果的果实是金黄色的,它里面是一棵十分大的果籽,整体呈球的形状,外表十分光滑,它的果期是在秋天。

  • 6月份水果当季有哪些(6月份水果当季都有哪些)

    6月份水果当季有哪些6月份水果当季的有西瓜,哈密瓜,油桃,菠萝,荔枝,火龙果,樱桃,杨梅,香瓜。这些都是营养价值比较丰富的水果,含有多种营养物质。例如维生素,蛋白质,有机酸等等,多吃对人体健康有利。不过还是要注意购买时要挑选自然成熟的,且成熟度比较好的,口感最佳。

  • 秦国名将白起和王翦(战国四大名将白起)

    战国四大名将,是中国历史上战国末期的四位伟大的军事战将。这四位名将分别是,秦国的白起与王翦,赵国的廉颇与李牧,能够被人评选为战国四大名将,自然有着他们的过人之处。他们各自为自己的国家立下赫赫战功,备受人民爱戴,然而权臣往往是君王猜忌的对象,尤其是掌有兵权的权臣,更是君王的心腹大患。果然不出王翦所料,李信被楚国击败,秦王嬴政大怒,并亲自去向王翦道歉,把六十万大军交给王翦,王翦带兵平定了楚国。

  • 怎么把微信给锁掉(快给微信上把锁)

    小陈赶紧在姐姐的陪同下赶到派出所报案,经调查后案件真相大白:小陈的同事班某,将小陈的银行卡绑到了自己的微信上,然后借用小陈的手机微信验证了密码。绑定成功之后,班某共计发红包五十七次,转账两次,累计金额达到一万六千余元。当然有,那就是使用微信锁的锁伪装功能。

  • 春风一度破镜重圆小说推荐(小说一剑夺命从他身上仿佛看到了西门吹雪的影子)

    人群再次哗然,继辰天之后,雪落兮也挑战古风,但与之前不同,古风毫无疑问必败。"淡雅声再次传来,雪落兮美丽倩影已经登台,现在只等古风。"场上,只剩下剑公子,鬼手夺命,公孙静,以及百里凤雪。两女再上战台,百里凤雪依旧冷艳,而那公孙静宛如清莲。"公孙静没有立刻认输,而是选择战斗。"公孙静咬着牙脸色苍白如纸的说道。"百里凤雪小姐胜,接下来进入决赛,休息半个时辰之后开始。"百里飞扬宣布结果。

  • 波轮洗衣机买什么品牌的好(波轮洗衣机什么牌子好)

    波轮洗衣机买什么品牌的好在购买洗衣机的时候有些人会选择波轮,觉得波轮的洗衣机自己用更加的合适。很多人买这个类型的洗衣机也不知道有哪些选购技巧,来看看波轮洗衣机有什么选购技巧。波轮洗衣机的牌子具体哪个好其实并没有一个完全的答案,你要买个好用的波轮洗衣机并不难。建议大家在买波轮洗衣机之前要能够好好看看自己的需求,以自己的需求来核心选择。

  • 星星是怎么形成的(关于星星形成原因)

    星星指的是肉眼可见的宇宙中的天体。星星内部的能量的活动使星星变的形状不规则。在我们的角度来看,星星不是形成,而是出现在我们可观测的范围内。每一个星球的灭亡,都会伴随着陨石、石头的出现,经过太阳的照射就是所谓的星星。所以金星距离地球最近的时候,看起来也只有月球的1/30。火星,只有地球一半大,却比金星还要远一点。木星,是太阳系最大的行星,但是它比太阳小10倍,却比太阳距离地球还要远上四倍。

  • 电视4k和8k啥区别(4K和8K电视的区别是什么)

    很多人可能都知道4K和8K电视的首要区别就是分辨率。4K电视是分辨率为3840*2160的电视,8K电视分辨率则是7680*4320,足足是4K的四倍。简单点来说,相比4K电视,在相同的距离下,8K电视能让你看到更多的画面,而且看到的物体细节更多,比如人物皮肤上的细微毛发都清晰可见。除了分辨率的提升,8K电视在其他方面上也有明显的改变。此外,8K电视使用了高动态对比第二代技术,在画面的明暗细节处理部分有很大的提升,整体画质更好。

  • 瘦身减肥汤教程(紫菜减肥汤任性甩肉女王)

    更重要的是紫菜中被人们比喻为“脑黄金”的二十碳五烯酸含量高达30%。紫菜含有多种维生素,B族维生素的含量与蔬菜相比毫不逊色。紫菜中B族维生素特别是在陆生植物中几乎不存在的维生素B12的含量很高,以干物计,维生素B12的含量与鱼肉相近。维生素B12有活跃脑神经,预防衰老和记忆力衰退,改善忧郁症之功效。它含有大量可以降低有害胆固醇的牛磺酸,有利于保护肝脏。

  • 7岁宝宝读什么课外书好(选择一些孩子自己喜欢的图书)

    接下来我们就一起去了解一下吧!如果家长推荐了孩子不喜欢看的课外书是没有用的。这个年龄段,应当从小培养孩子掌握一些阅读方法和技巧,更有利于孩子大量的阅读。孩子阅读时,家长最好不要去打扰孩子,这样会影响孩子的专注力。这个阶段,建议孩子多读书绘本类、童话类、故事类、教育类等书籍,不宜去读难以理解道理高深的书籍,毕竟孩子还有童真。